leetcode 15. 3Sum

来源:互联网 发布:新浪微博点赞软件 编辑:程序博客网 时间:2024/06/06 03:58

这里写图片描述

  这是leetcode里面点赞数比较多的题,难度不大但是不知道技巧会觉得难以解决。题干很简洁,从一个数组中找出和为0的三个元素,组成一个三元组,返回不重复的所有满足条件的三元组。这里有两个问题需要解决,怎样才能从无序的数组中找出满足条件的三元组,怎样才能保证它们不重复。查看这题的讨论区(Discuss栏)后,赞同数最多的那条令我恍然大悟。

  从无序的数组中查找难度比较大,所以可以先将数组排序,形成增序数组,然后对于数组中的元素nums[i],假定它是满足条件的三元组中最小的元素(i从0到nums.size()-3,因为某个满足条件的三元组中最小元素的元素在原数组中至多是第3大),则其他两个元素之和应该是-nums[i]。在num[i]的右边设置游标lo为i+1,hi为nums.size()-1,如果nums[lo]和nums[hi]的和为-nums[i],则找到了一个满足条件的三元组,保存,然后lo减一,hi加一。如果nums[lo]+nums[hi]小于-nums[i],说明nums[lo]过小,则lo加一;否则nums[hi]过大,hi减一。

  为了解决重复问题,在取最小元素的过程中,遇到nums[i]和它前一个元素值相等的情况,跳过nums[i]。当找到一个满足条件的三元组,lo减一之后,遇到nums[lo]和它前一个元素相等,lo继续加一,直到不等,hi同理。

  以下是实现代码

class Solution {public:    vector<vector<int>> threeSum(vector<int>& nums) {        vector<vector<int>> result;        if (nums.size() < 3)            return result;        sort(nums.begin(), nums.end());        for (int i = 0; i < nums.size() - 2; i++) {            if (i != 0) {                if (nums[i] == nums[i - 1])                    continue;            }            int twosum = 0 - nums[i];            int lo = i + 1, hi = nums.size() - 1;            while (lo < hi) {                if (nums[lo] + nums[hi] == twosum) {                    vector<int> vec;                    vec.push_back(-twosum);                    vec.push_back(nums[lo]);                    vec.push_back(nums[hi]);                    result.push_back(vec);                    lo++;                    hi--;                    while ((lo < hi)&&(nums[lo] == nums[lo - 1]))                         lo++;                    while ((lo < hi)&&(nums[hi] == nums[hi + 1]))                        hi--;                } else {                    if (nums[lo] + nums[hi] < twosum) {                        lo++;                    } else {                        hi--;                    }                }            }        }        return result;    }};
原创粉丝点击