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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值