經典演算法 | 求解陣列中的4個數的和為指定數的所有組合
給你一個數,問你陣列中的哪四個數的和為指定的target,這四個數不允許出現重複的數。
這一題並不難,但是非常的複雜,首先設定一個i和j,遍歷i和j之間的所有數,這個過程並難,但是剪枝比較複雜,並且為了防止出現重複的數,需要使用非常複雜的過濾函式
首先需要對陣列進行排序,實際上很多涉及到陣列的題目都首先需要對陣列進行排序,能夠節省很多的時間,
首先是if (nums[i] + nums[i + 1] + nums[i + 2] + nums[j] > target) { goto breakB; }
else if (nums[i] + nums[i + 1]
{
pushOn(nums, result, i, i + 1, i + 2, j);
goto breakB;
}
if (nums[i] + nums[j - 1] + nums[j - 2] + nums[j] < target) goto breakC;
else if (nums
{
pushOn(nums, result, i, j - 1, j - 2, j);
goto breakC;
}
這幾句是為了防止出現不可能的解,
然後是while (j + 1 < n&&nums[j + 1] == nums[j]) j++;
while (i + 1 <= n - 4 &&nums
通過這兩句能夠防止出現重複的解,為了防止出現重複的解,
if (tmp == tmpTarget)
{
pushOn(nums, result, i, left, right, j);
right--;
left++;
while (right > left&&nums[right + 1] == nums[right]) right--;
while (right > left&&nums[left - 1] == nums[left]) left++;
}
else if (tmp <tmpTarget)
{
left++;
while (right > left&&nums[left - 1] == nums[left]) left++;
}
else
{
right--;
while (right > left&&nums[right + 1] == nums[right]) right--;
}
這幾句也需要加上,這樣才能成功的防止出現重複的解
我覺得這一題雖然沒有特別的技巧,但是光復雜度就已經能算是hard題了
class Solution {
public:
void pushOn(vector<int>& nums,vector<vector<int>>&result, int a, int b, int c, int d)
{
vector<int>p;
p.push_back(nums[a]);p.push_back(nums[b]); p.push_back(nums[c]); p.push_back(nums[d]);
result.push_back(p);
}
vector<vector<int>>fourSum(vector<int>& nums, int target) {
vector<vector<int>>result;
sort(nums.begin(),nums.end());
intn = nums.size();
intleft, right,tmpTarget,tmp;
for(int i = 0; i <= n - 4; )
{
for(int j = i + 3; j < n;)
{
while(j + 1 < n&&nums[j + 1] == nums[j]) j++;
if (nums[i] + nums[i + 1] + nums[i + 2] +nums[j] > target) { goto breakB; }
elseif (nums[i] + nums[i + 1] + nums[i + 2] + nums[j] == target)
{
pushOn(nums,result, i, i + 1, i + 2, j);
gotobreakB;
}
if(nums[i] + nums[j - 1] + nums[j - 2] + nums[j] < target) goto breakC;
elseif (nums[i] + nums[j - 1] + nums[j - 2] + nums[j] == target)
{
pushOn(nums,result, i, j - 1, j - 2, j);
gotobreakC;
}
left= i + 1; right = j - 1; tmpTarget = target - nums[i] - nums[j];
while (left < right)
{
tmp= nums[left] + nums[right];
if(tmp == tmpTarget)
{
pushOn(nums,result, i, left, right, j);
right--;
left++;
while(right > left&&nums[right + 1] == nums[right]) right--;
while(right > left&&nums[left - 1] == nums[left]) left++;
}
elseif (tmp < tmpTarget)
{
left++;
while(right > left&&nums[left - 1] == nums[left]) left++;
}
else
{
right--;
while(right > left&&nums[right + 1] == nums[right]) right--;
}
}
breakC:;
j++;
}
breakB:;
while(i + 1 <= n - 4 &&nums[i + 1] == nums[i]) i++; i++;
}
returnresult;
}
};