您的位置:首页 > 其它

LeetCode No.15 3Sum

2016-10-29 01:36 246 查看
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]
]




====================================================================================

题目链接:https://leetcode.com/problems/3sum/

题目大意:给定一个数组,求数组中三个数(不重复)能构成和为0的所有集合(集合内数值从小到大排序,而且集合不能重复)。
思路:最直接的做法就是三重循环扫过去,遇到符合条件的集合就存下来,然后再用一个算法筛除重复的集合,很强很暴力,但是时间复杂度为O(N^3)。很不幸超时了。能不能有一个更快的方法呢?

先对给定的数组从小到大排个序,我们先确定集合内最小的那个数nums[i],其中 0 < i < n - 2,然后我们用一个左指针left(下标为i+1,,即集合最小值的下一个),一个右指针right(下标为n-1,即最大一个值),当三个数之和小于0时,左指针右移一位;但三个数之和大于0时,右指针左移一位;当三个数之和等于0时,记录下当前值,左指针右移,右指针左移,以此类推。

注意点:当数组中出现多个同样数值,要注意除重,除重步骤代码有标出。

附上代码:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector < vector <int> > ans ;
        ans.clear() ;
        int n = nums.size() ;
        sort ( nums.begin() , nums.end() ) ;
        for ( int i = 0 ; i < n - 2 ; i ++ )
        {
            if ( i && nums[i] == nums[i-1] )//除重
                continue ;
            int left = i + 1 , right = n - 1 ;
            while ( left < right )
            {
                int sum = nums[left] + nums[right] + nums[i] ;
                if ( ! sum )
                {
                    ans.push_back ( { nums[i] , nums[left] , nums[right] } ) ;
                    while ( ++ left < right && nums[left] == nums[left-1] ) ;//除重
                    while ( left < -- right && nums[right] == nums[right+1] ) ;//除重
                }
                else if ( sum < 0 )
                    left ++ ;
                else
                    right -- ;
            }
        }
        return ans ;
    }
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: