zoukankan      html  css  js  c++  java
  • [Note] 2020.6.12 每日一题 三数之和

    题目

    给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
    
    注意:答案中不可以包含重复的三元组。
    
     
    
    示例:
    
    给定数组 nums = [-1, 0, 1, 2, -1, -4],
    
    满足要求的三元组集合为:
    [
      [-1, 0, 1],
      [-1, -1, 2]
    ]
    
    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/3sum
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
    

    思路

    1. 3重循环暴力法
    2. 官方解法,在3种循环暴力法的基础上加入双指针,将复杂度从O(N3)变为O(N2)。
      首先注意两点,第一和为0,第二无重复。那么首先将序列排序后,开始三重循环枚举a,b,c,此时a<=b<=c是必然成立的;在确定a的情况下,若有a+b+c=0, 那b此时想右移一位得到b1后,令a+b1+c1=0的c1必然比c更小,所以c的取值c1应该是向c的左边序列找。因此将b和c的这两重循环是高度依赖的,可以通过双指针(一个自左往右,一个自右往左)将搜索复杂度从O(N^2)变为O(N)。

    代码

    • 思路1:
    class Solution:
        def threeSum(self, nums: List[int]) -> List[List[int]]:
            resultSet = {}
            for i in range(len(nums)):
                first = nums[i]
                for j in range(i+1, len(nums)):
                    middle = nums[j]
                    for k in range(j+1, len(nums)):
                        end = nums[k]
                        if (first + middle + end) == 0:
                            tmp = [first, middle, end]
                            tmp.sort()
                            first1,middle1,end1 = tmp
                            if first1 in resultSet:
                                if middle1 in resultSet[first1]:
                                   resultSet[first1][middle1].add(end1)
                                else:
                                    resultSet[first1][middle1] = set([end1])
                            else:
                                resultSet[first1]={middle1: set([end1])}
            resultList = []
            for key,v in resultSet.items():
                for k2,v2 in v.items():
                    while len(v2)>0:
                        resultList.append([key, k2, v2.pop()])
            return resultList
    

    毫无疑问,在这种平台上,这种无效率的做法是会超时的。

    1. 思路2:
    class Solution:
        def threeSum(self, nums: List[int]) -> List[List[int]]:
            resultSet = []
            nums.sort()
            for i in range(len(nums)):
                if i!=0 and (nums[i] ==  nums[i-1]):
                    continue
    
                first = nums[i]
                endInd = len(nums) - 1
    
                for j in range(i+1, len(nums)):
                    if j!=i+1 and (nums[j] == nums[j-1]):
                        continue
    
                    middle = nums[j]
    
                    while endInd>j and  (first + middle + nums[endInd]) > 0:
                        endInd -= 1
                    if endInd>j and (first + middle + nums[endInd]) == 0:
                        resultSet.append([first, middle, nums[endInd]])
                    
            return resultSet
    
  • 相关阅读:
    013.ES6 -对象字面量增强型写法
    012. ES6
    011. ES6 语法
    10. 9. Vue 计算属性的setter和getter 以及 计算属性的缓存讲解
    4. Spring MVC 数据响应方式
    3. SpringMVC 组件解析
    9. Vue 计算属性
    【洛谷 2984】给巧克力
    【洛谷 1821】捉迷藏 Hide and Seek
    【洛谷 1821】银牛派对Silver Cow Party
  • 原文地址:https://www.cnblogs.com/immortalBlog/p/13098544.html
Copyright © 2011-2022 走看看