LeetCode No.15 3Sum

来源:互联网 发布:ae中文版 mac 编辑:程序博客网 时间:2024/06/05 16:51

Given an array S of n integers, are there elements abc 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 ;    }};


0 0