zoukankan      html  css  js  c++  java
  • 15. 3Sum_左右开工,遍历找出符合目标的数字

    题目:

    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]
    ]
    代码:
    题目意思很简单:从数组中挑出三个数字,相加和为0,返回所有满足条件的结果:
    第一反应,当然是遍历3次,吭哧吭哧写完了:
        def threeSum(self, nums):
            """
            :type nums: List[int]
            :rtype: List[List[int]]
            """
            nums.sort()
            result = []
            for x in range(0,len(nums)-2):    
                for i in range(x+1,len(nums)-1):
                    #print(i,nums[i],result)
                    #if self.judge(nums[i],result):continue
                    for j in range(i+1,len(nums)):
                        #if self.judge(nums[j],result):continue
                        if(nums[x]+nums[i]+nums[j]==0):
                            if [nums[x],nums[i],nums[j]] not in result:
                                result.append([nums[x],nums[i],nums[j]])                   
            return result
    但是,问题来了,LeetCode提交测试会超时,测试数据是一串126个元素的数组,并且有120组符合条件的答案。
    这种遍历的方法试了一下,大概需要0.36s,确实不快,必定时间复杂度有O(n^3)了
    想啊想,试了很多种,都不行,只能百度了一下大神算法,一时,只用了0.003秒,而且准确的说,除去枚举第一个数之外,其余只需要遍历一遍:
    总共的时间复杂度不到:O(n^2)
    拷贝过来记录,并共大家参考学习:
        def threeSum2(self, nums):
            '''
                题意:求数列中三个数之和为0的三元组有多少个,需去重
                暴力枚举三个数复杂度为O(N^3)
                先考虑2Sum的做法,假设升序数列a,对于一组解ai,aj, 另一组解ak,al
                必然满足 i<k j>l 或 i>k j<l, 因此我们可以用两个指针,初始时指向数列两端
                指向数之和大于目标值时,右指针向左移使得总和减小,反之左指针向右移
                由此可以用O(N)的复杂度解决2Sum问题,3Sum则枚举第一个数O(N^2)
                使用有序数列的好处是,在枚举和移动指针时值相等的数可以跳过,省去去重部分
            '''       
            nums.sort()
            res = []
            length = len(nums)
            for i in range(0, length - 2):
                if i and nums[i] == nums[i - 1]:
                    continue
                target = nums[i] * -1
                left, right = i + 1, length - 1
               
           while left < right:
                    if nums[left] + nums[right] == target:
                        res.append([nums[i], nums[left], nums[right]])
                        right -= 1
                        left += 1
                        while left < right and nums[left] == nums[left - 1]:
                            left += 1
                        while left < right and nums[right] == nums[right + 1]:
                            right -= 1
                    elif nums[left] + nums[right] > target:
                        right -= 1
                    else:
                        left += 1
            return res   
  • 相关阅读:
    msp430入门编程41
    msp430入门编程40
    msp430入门编程37
    msp430入门编程36
    msp430入门编程35
    msp430入门编程34
    msp430入门编程33
    msp430入门编程31
    msp430入门编程32
    msp430入门编程30
  • 原文地址:https://www.cnblogs.com/yuanzhaoyi/p/6032980.html
Copyright © 2011-2022 走看看