LeetCode-15、16:3Sum & 3Sum Closest(三數的和)

題目:3 Sum

Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note:

  • The solution set must not contain duplicate triplets.

例子:

Given array nums = [-1, 0, 1, 2, -1, -4],

A solution set is:

[
  [-1, 0, 1],
  [-1, -1, 2]
]

問題解析:

給定數組,返回數組中和爲0的三元組。

鏈接:

思路標籤

算法:雙指針

解答:

  • 以LeetCode-1:Two Sum 的思想,因爲a+b+c=0,那麼a+b=-c;
  • 不同的是,我們需要返回的是元素本身,所以不需要使用關聯容器map;
  • 同時,數組中存在多種不同的三元組滿足條件;
  • 另外,因爲數組中存在重複元素,所以有可能會得到相同的元素相同的三元組,但是隻能加入其中的一組;
  • 所以爲了避免重複問題,我們先將數組排序,將每個元素的負值作爲target以尋找另外兩個元素;
  • 在尋找另外兩個元素的時候,我們以兩個指針分別指向目標元素的下一個位置和數組的尾部,通過比較兩個數和與目標值的大小來進行尋找;
  • 需要在每次找到一組三元組後對後面的重複元素進行跳過處理;同時在每個目標值target進行完畢後同樣也進行跳過處理。
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int> > ret;

        sort(nums.begin(), nums.end());
        for(int i=0; i<nums.size(); ++i){
            int low = i+1;
            int high = nums.size()-1;
            int target = -nums[i];

            while(low < high){
                int sum = nums[low] + nums[high];

                if(sum < target)
                    low++;
                else if(sum > target)
                    high--;
                else{
                    vector<int> triplets(3,0);
                    triplets[0] = nums[i];
                    triplets[1] = nums[low];
                    triplets[2] = nums[high];
                    ret.push_back(triplets);

                    while(low < high && nums[low] == triplets[1]) low++;
                    while(low < high && nums[high] == triplets[2]) high--;
                }
            }

            while(i+1<nums.size() && nums[i+1] == nums[i])
                i++;
        }
        return ret;
    }
};

題目:3 Sum Closest

Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

例子:

Given array nums = [-1, 2, 1, -4], and target = 1.

The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

問題解析:

給定數組及目標值,返回數組中和與目標值最接近的三元組。

鏈接:

思路標籤

算法:雙指針

解答:

  • 以LeetCode-15:3 Sum 的思想,我們依然是先遍歷給出三元組中的一個候選,然後以雙指針的形式選擇剩下的兩個元素;
  • 因爲我們需要求最接近目標值的和,所以我們對當前每個三元組進行計算,通過絕對值比較,每次都記錄當前的最小絕對值和最接近目標值的和;
  • 通過比較差值對兩個值進行選擇。
class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {  
        sort(nums.begin(), nums.end());

        int closestSum = nums[0] + nums[1] + nums[2];
        int minAbs = abs(closestSum - target);
        for(int i=0; i<nums.size(); ++i){
            int first = nums[i];
            int index2 = i+1;
            int index3 = nums.size()-1;
            while(index2 < index3){
                int tempSum = first + nums[index2] + nums[index3];
                int diff = tempSum - target;
                if(abs(diff) < minAbs){
                    minAbs = abs(diff);
                    closestSum = tempSum;
                }
                if(diff < 0) 
                    index2++;
                else if(diff > 0) 
                    index3--;
                else
                    return closestSum;
            } 
        }
        return closestSum;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章