leetcode 3Sum

来源:互联网 发布:安装软件出现2503 编辑:程序博客网 时间:2024/05/17 05:01

https://leetcode.com/problems/3sum/

Note1

这里可以利用two sum binary search的方法,对于每一个i,利用j, k two pointers 去找sum 等于-nums[i].

Note2

如果是O(N^2)的遍历,要思考是否可以sort一下,然后用two pointers. 因为最后只返回不重复的值,例如,如果a<b, 遍历a的时候会找到(a,b),遍历b的时候会找到a,所以只要sort一下,遍历到a的时候,只需要遍历a以后的值就行。这样没有降低复杂度,依然还是N^2的方法。但是可以有效的去重复,并且还要注意i,j,k 在遍历的时候对应的元素也要去重复。

sort之后就有大小关系,就可能只需要遍历一部分或者可以减枝

另一个sort的原因就是题目要求Elements in a triplet (a,b,c) must be in non-descending order.

参考http://www.cnblogs.com/zuoyuan/p/3699159.html

解题思路:1,先将数组排序。

     2,排序后,可以按照TwoSum的思路来解题。怎么解呢?可以将num[i]的相反数即-num[i]作为target,然后从i+1到len(num)-1的数组元素中寻找两个数使它们的和为-num[i]就可以了。下标i的范围是从0到len(num)-3。

     3,这个过程要注意去重。就是说j指向的数可能有很多个,k指向的数也有很多个

     4,时间复杂度为O(N^2)。

class Solution:    # @return a list of lists of length 3, [[val1,val2,val3]]    def threeSum(self, num):        num.sort()        res = []        for i in range(len(num)-2):            if i == 0 or num[i] > num[i-1]:#这里因为num已经sort了,所以这里仅仅是说i如果指向了与上一个元素相同的数,那么就continue。我们只考虑第一个。sort了之后也会有相同的值,e.g.{1,1,1,2,2},只考虑第一个1,第一个2                left = i + 1; right = len(num) - 1                while left < right:                    if num[left] + num[right] == -num[i]:                        res.append([num[i], num[left], num[right]])                        left += 1; right -= 1                        while left < right and num[left] == num[left-1]: left +=1#去掉重复值                        while left < right and num[right] == num[right+1]: right -= 1                    elif num[left] + num[right] < -num[i]:#如果小于target,那么就要增加num[left] + num[right],因为sorted,所以left向右移就行。                        while left < right:#这里也是去掉重复值,可以改造不用break                            left += 1                            if num[left] > num[left-1]: break                    else:                        while left < right:                            right -= 1                            if num[right] < num[right+1]: break        return res

当num[left] + num[right] < -num[i]时,我们可以不用break

                while left < right:                    if num[left] + num[right] == -num[i]:                        res.append([num[i], num[left], num[right]])                        left += 1; right -= 1                        while left < right and num[left] == num[left-1]: left +=1#去掉重复值                        while left < right and num[right] == num[right+1]: right -= 1                    elif num[left] + num[right] < -num[i]:#如果小于target,那么就要增加num[left] + num[right],因为sorted,所以left向右移就行。                        #print (left,right)                        while left < right and num[left + 1] == num[left]:                            left += 1                        left += 1                    else:                        while left < right and num[right - 1] == num[right]:                            right -= 1                        right -= 1

参考http://codesays.com/2014/solution-to-3sum-by-leetcode/ 的code
这里要注意i,j,k都要去重复。
my code

class Solution(object):    def threeSum(self, nums):        """        :type nums: List[int]        :rtype: List[List[int]]        """        if len(nums) < 3:            return []        nums.sort()        #after sort(), we just need two pointers to scan        res = []        i = 0        while i < len(nums) - 2:                    j = i + 1            k = len(nums) - 1            while j < k:                if nums[i] + nums[j] + nums[j] > 0 or nums[i] + nums[k] + nums[k] < 0:                    break                if nums[i] + nums[j] + nums[k] == 0:                    res.append([nums[i], nums[j], nums[k]])                    j += 1                    while j < k and nums[j] == nums[j - 1]:                        j += 1                    k -= 1                    while k > j and nums[k] == nums[k + 1]:                        k -= 1                elif nums[i] + nums[j] + nums[k] < 0:                    j += 1                    while j < k and nums[j] == nums[j-1]:   j += 1                else:                    # Skip duplicate num[k+1]                    k -= 1                    while k > j and nums[k] == nums[k+1]:   k -= 1            i += 1            while i < len(nums) - 2 and nums[i] == nums[i - 1]:                i += 1        return res
0 0
原创粉丝点击