• LeetCode15. 三数之和


    15. 三数之和

    描述

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

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

    示例

    例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
    
    满足要求的三元组集合为:
    [
      [-1, 0, 1],
      [-1, -1, 2]
    ]
    

    思路

    思路一

    这种数值列表中有加减的题目,排序后可能会更加方便些。

    固定两个数,将 target 设置为两个数之和的相反数,看 target 是否在列表中,若在,则为一个结果。

    class Solution:
        def threeSum(self, nums):
            """
            :type nums: List[int]
            :rtype: List[List[int]]
            """
            ret = []
            # 数组题,其中有加减操作的,排序后会方便很多
            nums.sort()
            len_nums = len(nums)
    
            for i in range(len_nums - 1):
                for j in range(i+1, len_nums):
                    # 固定下来两个数,如果另外一个数也在数组中,则为一个结果
                    if -(nums[i]+nums[j]) in nums[j+1:]:
                        a_ret = [nums[i], nums[j], -(nums[i]+nums[j])]
                        if a_ret not in ret:
                            ret.append(a_ret)
    
            return ret
    

    但是这种方法有两层循环,果然报了 TLE(Time Limit Exceeded) 错误。

    思路二

    固定一个数,设置 target 为其他两个数之和的相反数,即 0 - 当前数,由两头向中间遍历数组,找到之和符合 target 的两个数即是一个结果。

    class Solution:
        def threeSum(self, nums):
            """
            :type nums: List[int]
            :rtype: List[List[int]]
            """
            ret = []
            nums.sort()
    
            for i in range(0, len(nums)):
                # 若存在相同数,跳过以减少计算
                if i > 0 and nums[i] == nums[i-1]:
                    continue
    
                target = 0 - nums[i]
                start, end = i+1, len(nums)-1
    
                while start < end:
                    # 头尾之和大于目标值,尾向前移一位
                    if nums[start] + nums[end] > target:
                        end -= 1
                    # 头尾之和小于目标值,头向后移一位
                    elif nums[start] + nums[end] < target:
                        start += 1
                    # 头尾之和等于目标值,是一个结果,添加进去
                    # 头尾都移动一位
                    else:
                        ret.append([nums[i], nums[start], nums[end]])
                        start += 1
                        end -= 1
                        # 若移动后有重复值,继续移动
                        while start < end and nums[start] == nums[start-1]:
                            start += 1
                        while start < end and nums[end] == nums[end+1]:
                            end -= 1
    
            return ret
    
    

    GitHub地址:https://github.com/protea-ban/LeetCode

  • 相关阅读:
    Java中的CopyOnWrite
    Collection和Collections的区别
    java中值类型与引用类型的关系
    Xml的用途
    js弹框的3种方法
    文件夹重定向失败解决方案
    网络管理人员经常遇到的十个问题(转载)
    QTP之下拉列表单选框…
    Windows脚本宿主对象模型
    QTP报错“缺少对象WScript”
  • 原文地址:https://www.cnblogs.com/banshaohuan/p/9667576.html
Copyright © 2020-2023  润新知