15.3Sum

description:

 15 3Sum    21.8%Medium

Given an array S of n integers, are there elements a, b, c in S 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.

For example, given array S = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

my solution:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        std::sort(nums.begin(), nums.end());
        std::vector<vector<int>> result;
        int tempSum = 0, twoSum = 0;
        int newBegin = 0;
        int newEnd = nums.size() - 1;
        for (int i = 0; i < nums.size(); ++i)
        {
        	twoSum = -nums[i];
        	newBegin = i + 1;
        	newEnd = nums.size() - 1;

        	while(newBegin < newEnd) {
        		tempSum = nums[newBegin] + nums[newEnd];
        		if(tempSum < twoSum) {
        			newBegin++;
        		} else if(tempSum > twoSum) {
        			newEnd--;
        		} else {
        			std::vector<int> v;
        			v.push_back(nums[i]);
        			v.push_back(nums[newBegin]);
        			v.push_back(nums[newEnd]);
        			result.push_back(v);
        			while (newBegin < newEnd && nums[newBegin] == v[1]) newBegin++;
                	while (newBegin < newEnd && nums[newEnd] == v[2]) newEnd--;
        		}
        	}
            while (i < nums.size() && nums[i + 1] == nums[i]) i++;
        	if(nums[i] > 0) break;
        }
        return result;
    }
};

thought:

这道题的思路就是把三个数相加转化成两个数相加。

首先,对数组进行排序,其次从头到尾遍历数组,对每个数字取反都当成所求两个数字的和进行处理。

然后以该数字为界限,向后寻找两个数字,使之相加为该数字的负值。其中为了减小开销,两数字分别从头和尾部找起,这样做能把2维问题转化成1维问题。

最后的优化就是,跳过相同的数字,同时当遍历的数字大于0时,结束搜索,因为大于0时,剩下两个数字皆大于0,所以不用继续了。

点赞