LintCode 三数之和

1. 三数之和

给出一个有n个整数的数组S,在S中找到三个整数a, b, c,找到所有使得a + b + c = 0的三元组。
样例
如S = {-1 0 1 2 -1 -4}, 你需要返回的三元组集合的是:
(-1, 0, 1)
(-1, -1, 2)
注意
在三元组(a, b, c),要求a <= b <= c。结果不能包含重复的三元组。

solution:
因为三元组的元素是按照递增的顺序,因此我们首先需要对S进行排序。然后保持两个前后索引来进行比较。
code

class Solution {
public:    
    /**
     * @param numbers : Give an array numbers of n integer
     * @return : Find all unique triplets in the array which gives the sum of zero.
     */
    vector<vector<int> > threeSum(vector<int> &nums) {
        // write your code here   
        vector<vector<int>> res;
        sort(nums.begin(), nums.end()); //对数组进行排序
        int i = 0 , last = nums.size()-1;
        while (i < last) {
            int a = nums[i], j = i + 1, k = last;
            while (j < k) {
                int b = nums[j], c = nums[k];
                int sum = a + b + c;
                if (sum == 0)  res.push_back({a,b,c});
                if (sum <= 0)  //注意不能含有相同的索引
                    while (nums[j] == b && j < k ) ++j;
                if (sum >= 0)
                    while (nums[k] == c && j < k) --k;
            }
            while (nums[i] == a && i < last) ++i;
        }
        return res;        
    }
};

2. 三数之和 II

给一个包含n个整数的数组S, 找到和与给定整数target最接近的三元组,返回这三个数的和。
样例
例如S = [-1, 2, 1, -4] and target = 1. 和最接近1的三元组是 -1 + 2 + 1 = 2.
注意
只需要返回三元组之和,无需返回三元组本身

solution: 只需要把前面的问题与0进行比较改成target就可以了。
code:

class Solution {
public:    
    /**
     * @param numbers: Give an array numbers of n integer
     * @param target: An integer
     * @return: return the sum of the three integers, the sum closest target.
     */
    int threeSumClosest(vector<int> nums, int target) {
        // write your code here
        if (nums.size() < 3)
            return accumulate(nums.begin(), nums.end(), 0);
        sort(nums.begin(), nums.end());
        int ans = nums[0] + nums[1] + nums[2];
        int i = 0, last = nums.size()-1;
        int diff = 0;
        while (i < last) {
            int a = nums[i], j = i + 1, k = last;
            while (j < k) {
                int b = nums[j], c = nums[k];
                int sum = a + b + c;
                if (abs(sum - target) < abs(ans - target)) 
                    ans = sum;
                if (ans == target)
                    return ans;
                if (sum < target)
                    while (nums[j] == b && j < k) ++j;
                if (sum > target)
                    while (nums[k] == c && j < k) --k;
            }
            while (nums[i] == a && i < last) ++i;
        }
        return ans;
    }
};

3. 四数之和

给一个包含n个数的整数数组S,在S中找到所有使得和为给定整数target的四元组(a, b, c, d)。
样例
例如,对于给定的整数数组S=[1, 0, -1, 0, -2, 2] 和 target=0. 满足要求的四元组集合为:
(-1, 0, 0, 1)
(-2, -1, 1, 2)
(-2, 0, 0, 2)
注意
四元组(a, b, c, d)中,需要满足a <= b <= c <= d
答案中不可以包含重复的四元组。

solution:思路和前面的三数之和是一样的,算法复杂度O(n^3).

class Solution {
public:
    /**
     * @param numbers: Give an array numbersbers of n integer
     * @param target: you need to find four elements that's sum of target
     * @return: Find all unique quadruplets in the array which gives the sum of 
     *          zero.
     */
    vector<vector<int> > fourSum(vector<int> nums, int target) {
        // write your code here
        sort(nums.begin(), nums.end());
        vector<vector<int>> res;
        int i = 0, last = nums.size()-1;
        while (i < last) {
            int a = nums[i], j = i + 1;
            while (j < last) {
                int b = nums[j], k = j + 1, l = last;
                while (k < l) {
                    int c = nums[k], d = nums[l];
                    int sum = a + b + c + d;
                    if (sum == target) res.push_back({a,b,c,d});
                    if (sum <= target) 
                        while (nums[k] == c && k < l) ++k;
                    if (sum >= target)
                        while (nums[l] == d && k < l) --l;
                }
                while (nums[j] == b && j < last) ++j;
            }
            while (nums[i] == a && i < last) ++i;
        }
        return res;
    }
};
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值