1. 程式人生 > >經典演算法 | 求解陣列中的4個數的和為指定數的所有組合

經典演算法 | 求解陣列中的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]

+ nums[i + 2] + nums[j] == target)

                  {

                       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

[i] + nums[j - 1] + nums[j - 2] + nums[j] == target)

                  {

                       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

[i + 1] == nums[i]) i++; i++;

通過這兩句能夠防止出現重複的解,為了防止出現重複的解,

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;

}

};