16 leetcode - 3Sum

3Sum

2Sum

先将数组排序,然后用两个指针分别从头和尾扫描。

class Solution(object):
    def twoSum(self, nums, target):
        if len(nums) < 2:
            return []
        nums.sort()
        first = 0
        last = len(nums) - 1
        while first < last:
            if nums[first] + nums[last] == target:
                return [nums[first],nums[last]]
            elif nums[first] + nums[last] < target:
                first += 1
            else:
                last -= 1
        return []

3Sum

题目

英文: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.
中文:一个数组,找出其中的三个数,让其相加为0.返回的结果不能包含重复组合
举例:
For example, given array S = [-1, 0, 1, 2, -1, -4],
A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]

方法

  1. 3Sum可以转化为2Sum问题,固定一个数num,然后利用2Sum的方法寻找和为target - num的另外的两个数。

  2. 结果去重。

    • 因为数组有序,对于 nums[i],寻找另外两个数时,只要从 nums[i+1] 开始找就可以了;

      原因:nums[0] ~ nums[i - 1]已经查找过是否会与nums[i]组成一组数,避免重复查找,也为了提高查找效率,从nums[i+1]查找即可。

    • 如果nums[i] 等于nums[i - 1],直接跳过;

      nums[i - 1] + x + y == target,nums[i] == nums[i - 1],重复结果,没意义啊…

      nums[i - 1]找全了所有能与nums[i - 1]组合的数,nums[i] == nums[i - 1],所以nums[i]再找也是重复结果。

code

#!/usr/bin/python
# -*- coding: utf-8 -*-
class Solution(object):
    def quicksort(self,a,start,end):#快排排序
        if not a or start >= end:
            return a
        temp = a[start]
        left,right = start,end
        while left < right:
            while a[right] >= temp and left < right:
                right -= 1
            a[left] = a[right]

            while a[left] <= temp and left < right:
                left += 1
            a[right] = a[left]
        a[left] = temp
        self.quicksort(a,start,left - 1)
        self.quicksort(a,left + 1,end)
        return a

    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        length = len(nums)
        if length < 3:  #小于三个的话肯定不行
            return []
        nums = self.quicksort(nums,0,length - 1)#排序
        result = []
        pos = 0 #固定一个数
        while pos < length - 2: #查找到倒数第三个就行了,保证剩余三个数
            #查找和为target - nums[pos]的另外的另个数
            #去掉重复结果,num[pos - 1]找全了所有能与num[pos - 1]组合的数,nums[pos]再找也是重复结果。
            while pos > 0 and nums[pos] == nums[pos-1] and pos < length - 2:
                pos += 1 
            target = - nums[pos]
            first = pos + 1   #从pos之后的元素查找就行了
            last = length - 1
            while first < last:
                if nums[first] + nums[last] == target:
                    result.append([nums[pos],nums[first],nums[last]])
                    #nums[first] + nums[last] + nums[pos] = 0,
                    #nums[first + 1] + nums[last] + nums[pos] = 0,nums[first] == nums[first + 1],重复结果
                    while nums[first] == nums[first + 1] and first < length -2:
                        first += 1
                    #同上
                    while nums[last] == nums[last - 1] and last > pos + 1:
                        last -= 1
                    #一个数变大,一个数减小,相加才可能得到target
                    last -= 1
                    first += 1
                elif nums[first] + nums[last] > target:#比target大,减小两数之和
                    last -= 1    
                else:#比target小,增大两数之和
                    first += 1
            pos += 1
        return result

if __name__ == "__main__":
    s = Solution()
    print s.threeSum([-2,0,0,2,2])
    print s.threeSum( [-1,0,1,2,-1,-4])
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值