leetcode——15. 三数之和

题目描述

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

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

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

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

解题思路

  • 先将给定 nums 排序,复杂度为 O(NlogN)O(NlogN)。
  • 异常判断
  • 因为 nums[j] > nums[i] > nums[k] >0 ,三个数中必须要有负数。
  • 使用双指针 前后夹击,遇到相同的元素,则跳过
  • 三数之和小于0,左边的指针i向右移动增大,并且要跳过所有的相同的元素
  • 三数之和大于0,右边的指针j向左移动减小,并且要跳过所有的相同的元素
  • 三数之和等于0,将组合添加到res,并且要跳过所有的相同的元素

代码

class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        nums.sort()
        res = []# 返回值

        if len(nums) <3:# 异常判断
            return []

        for k in range(len(nums) - 2):
            if nums[k] > 0: # 因为 nums[j] > nums[i] > nums[k]  
                break
            if k > 0 and nums[k] == nums[k-1]:
                continue # 跳过相同的元素
            i,j = k +1 ,len(nums) - 1 # 双指针 前后夹击
            while i < j :  
                s = nums[k] + nums[j] + nums[i] # 三数之和
                if s < 0:   # 三数之和小于0,左边的指针i向右移动增大,并且要跳过所有的相同的元素
                    i += 1j
                    while i < j and nums[i] == nums[i -1]:
                        i += 1i
                elif s > 0: # 三数之和大于0,右边的指针j向左移动减小,并且要跳过所有的相同的元素
                    j -= 1
                    while i < j and nums[j] == nums[j + 1]:
                        j -= 1
                else: # 三数之和等于0,将组合添加到res,并且要跳过所有的相同的元素
                    res.append([nums[k],nums[i],nums[j]]) 
                    i += 1
                    j -= 1
                    while i < j and nums[i] == nums[i - 1]:
                        i += 1
                    while i < j and nums[j] == nums[j + 1]:
                        j -= 1
        return res

算法复杂度分析

  • 时间复杂度为 O ( n 2 ) O(n^2) :

    • 数组排序 O ( n l o g n ) O(nlogn)
    • 遍历数组 O ( n ) O(n)
    • 算个指针遍历 O ( n ) O(n)
    • 总体 O ( n l o g n ) + O ( n ) O ( n ) = O ( n 2 ) O(nlogn) + O(n)*O(n) = O(n^2)
  • 空间复杂度 O ( 1 ) O(1) :

    • 指针使用常数大小的额外空间。
发布了160 篇原创文章 · 获赞 33 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/Heitao5200/article/details/102957993