zoukankan      html  css  js  c++  java
  • LeetCode 第15题-三数之和

    1. 题目

    2.题目分析与思路

    3.思路

    1. 题目

    给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

    注意:答案中不可以包含重复的三元组。

    例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

    满足要求的三元组集合为:
    [
    [-1, 0, 1],
    [-1, -1, 2]
    ]

    2. 思路

      这道题最直接想到的应该是两数之和,两数之和还是比较基础的,采用通知记录的方式,维护一个字典,看新的数是否属于这个字典的键即可。三数之和也可以使用类似的办法,但是题目要求的是不能有重复的,这就比较难办了,那可能只有先将其排序,然后判断一下他们是否在集合中,思路就显而意见了,代码如下:

    def threeSum(self, nums: List[int]) -> List[List[int]]:
            result = []
            for i,j in enumerate(nums):
                temp = nums[:i]+nums[i+1:]
                dic1 = {}
                dic2 = {}
                for count,k in enumerate(temp):
                    if k not in dic1:
                        dic1[-j-k] = k
                    else:
                        dic2[tuple(sorted([j,k,-j-k]))] = [j,k,-j-k]
            return dic2.values()

    3. 改进

        然而不幸的是,这个复杂度太高,跑不过所有case便会超时,在这之前我使用的是判断list是否在list中,这样的话更没有办法通过所有的case,复杂度太高,优化以后使用字典但还是在全是0的case失败了。

        经过修改后和一些边界条件,给出一个通过了case,但是极其慢的解法,我称其为无情解法:

    def threeSum(self, nums: List[int]) -> List[List[int]]:
            dic2 = {}
            if (len(set(nums) ) == 1)and (len(nums) > 2): #主要是去除全是0 的情况,全是0 就会导致最后的循环复杂度过高
                if 0 in set(nums):
                    return [[0,0,0]]
            for i,j in enumerate(nums):
                temp = nums[:i]+nums[i+1:]
                dic1 = {}
                for count,k in enumerate(temp):
                    if k not in dic1:
                        dic1[-j-k] = k
                    else:
                        dic2[tuple(sorted([j,k,-j-k]))] = [j,k,-j-k]
            return dic2.values()

       下面给出正确的解法,使用双指针

    class Solution:
        def threeSum(self, nums: List[int]) -> List[List[int]]:
            nums = sorted(nums)
            res = []
            dic1 = {}
            for i,j in enumerate(nums):
                if j > 0:
                    continue
                temp = nums[i+1:]
                left = 0
                right = len(temp)-1
                while(left < right):
                    
                    if j + temp[left]+temp[right] == 0:
                        dic1[(j,temp[left],temp[right])] = [j,temp[left],temp[right]]
                        # res.append([j,temp[left],temp[right]])
                        right -= 1
                    elif j + temp[left]+temp[right] > 0:
                        right -= 1
                    else:
                        left += 1
            return dic1.values()
  • 相关阅读:
    JavaScript总结
    Python-模块
    在VMware软件下创建CentOs虚拟机
    python 日常一记 基础
    python request 基于unittest 请求deom
    python 日常已记 列表去重
    电话拨号器
    Axure RP使用攻略--入门级(二)线框图元件
    Axure RP使用攻略--入门级(一)
    ArcGIS Server-发布地理编码服务
  • 原文地址:https://www.cnblogs.com/tjpeng/p/11621435.html
Copyright © 2011-2022 走看看