805. Split Array With Same Average

只是再次验证了自己之前的想法:难题目只是由几个小的,不太难的子题目组成的。把子题目明确定义出来,逐个击破即可。(另外下面的想法我之前想到了,只是没想到就是这么简单。。。。)
分成两组,两组平均值一样。那么总的平均值一样,可以算出来。那么我们就可以把题目转化为:是否能够一组数,它们的和是个数*平均值。那么这个个数也不是都可以的,因为这个个数乘以平均值也必须为整数。另外,我们可以找个数少的那一组,最多个数为sz/2。
class Solution {
public:
bool splitArraySameAverage(vector<int>& A) {
int sz = A.size();
int sum = accumulate(A.begin(), A.end(), 0);
sort(A.begin(), A.end(), greater<int>());//之前遇到的一个小技巧,加快速度
for (int i = 1; i <= sz / 2; ++i)
if (sum*i%sz == 0 && find(A, sum*i/sz, i)) {
return true;
}
return false;
}
private:
//A中能不能找到k个数,它们的和为target
bool find(vector<int>& A, int target, int k) {
return findHelper(A, target, 0, 0, k);
}
bool findHelper(vector<int>& A, int target, int tempSum, int idx, int k) {
if (tempSum == target && k == 0)
return true;
if (idx == A.size() || k == 0)
return false;
for (int i = idx; i < A.size(); ++i) {
if (tempSum + A[i] > target)
continue;
if (findHelper(A, target, tempSum + A[i], i + 1, k - 1))
return true;
}
return false;
}
};
虽然TLE,但是面试的时候说出这个已经够了吧。
或者写的更加简洁一点:
class Solution {
public:
bool splitArraySameAverage(vector<int>& A) {
int sz = A.size();
int sum = accumulate(A.begin(), A.end(), 0);
sort(A.begin(), A.end(), greater<int>());
for (int i = 1; i <= sz / 2; ++i)
if (sum*i%sz == 0 && find(A, sum*i/sz, i, 0)) {
//cout << sum * i / sz << " " << i << endl;
return true;
}
return false;
}
private:
//A中能不能找到k个数,它们的和为target
bool find(vector<int>& A, int target, int k, int i) {
if (k == 0)
return target == 0;
if (k + i > A.size())
return false;
return find(A, target - A[i], k - 1, i + 1) ||
find(A, target, k, i+1);
}
};
虽然仍然TLE。
可以通过的做法是背包dp,但是暂时理解上有些困难,之后再补充吧。
浙公网安备 33010602011771号