leetcode hot100 15. 三数之和 medium

👉 题目禁止的是:

下标重复(同一个元素不能用两次)

结果三元组重复(值完全相同的三元组不能出现两次)

👉 题目并不禁止:

值相同但来自不同位置的元素

由三维降到二维, 针对任意索引i的numsii+1,size )范围内不重复的twoSum target = - nums\[i;

  1. 排序数组,方便去重。
  2. 固定一个元素 numsi,用双指针扫描剩余部分的数组来寻找另外两个数。

时间复杂度:O(n²)

排序是 O(n log n)。

双指针扫描是 O(n)。对于每个 i,双指针的扫描是 O(n) 的操作,而外层循环遍历了 n 个元素。

总的时间复杂度为 O(n²) +O(n log n) = O(max(n log n, n²)) = O(n²)

没有使用额外的存储结构(例如哈希表、栈等),而是仅使用了常数级的空间(如变量 i, left, right, res)。因此,空间复杂度是 O(1)

python 复制代码
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:

        if len(nums) < 3:
            return []

        nums.sort()   # 从小到大排序
        res =[]

        for i in range(len(nums)):
            if nums[i] >0:    # 已排序,第一个就>0,后面不会有匹配的, 退出当前循环
                break         # 不能 return [], 因为之前的循环res可能已经有值,只能break或return res 
            if i>0 and nums[i] == nums[i-1]:  # 当前nums[i]与nums[i-1]相同,前面已经处理过,跳过
                continue
            
            # 由三维降到二维,开始左右指针: 针对任意索引i的nums[i] 求[i+1,size )范围内不重复的twoSum target = - nums[i];
            # twoSum 开始
            left = i+1
            right = len(nums)-1
            while left < right:
                target = 0-nums[i]

                # 正好找到
                if nums[left] + nums[right]  == target:
                    res.append([nums[i], nums[left], nums[right]])
                    while(left < right and nums[left]==nums[left+1]):    # 跳过重复元素
                        left +=1
                    while(left < right and nums[right]==nums[right-1]):  # 跳过重复元素
                        right -= 1

                    # 正常移动双指针
                    left  += 1
                    right -= 1

                # 没找到
                elif nums[left] + nums[right] > target:  # 已排序,说明要再小一点
                    right -= 1  # 右指针左移 
                else:   #nums[left] + nums[right] < target:  # 已排序,说明要再大一点
                    left +=1 


        return res

在发现一个三元组时,为什么不是直接跳过首尾:left += 1;right -= 1,而是要判断

numsleft == numsleft + 1:

numsright == numsright - 1
避免重复三元组:因为数组是排过序的,可能会遇到值相同的元素。为了避免返回重复的三元组,需要跳过相同的元素。

假设数组已经排序:-1, -1, 0, 1, 1

我们找到的三元组是 -1, 0, 1。那么:

左指针 left 现在指向 0。

右指针 right 现在指向 1。

如果我们直接移动指针,左指针 left 会指向下一个 0,右指针 right 会指向下一个 1,这时候我们会重复添加 -1, 0, 1 这个三元组。为了避免这种情况,要跳过这些相同的元素

相关推荐
To_OC6 小时前
LC 131 分割回文串:刚学回溯时,我连怎么切字符串都想不明白
javascript·算法·leetcode
旖-旎7 小时前
LeetCode 518:零钱兑换||(完全背包)—— 题解
c++·算法·leetcode·动态规划·背包问题
To_OC8 小时前
LC 42 接雨水:暴力超时卡半天?前后缀数组一用就通了
javascript·算法·leetcode
delishcomcn9 小时前
AI视觉识别+分切算法:电化铝缺陷检测与裁切一体化解锁
人工智能·算法
触底反弹9 小时前
深入理解大模型采样:Temperature、Top-K、Top-P 的原理与实战
人工智能·算法·面试
雪碧聊技术9 小时前
力扣 LCR 091. 粉刷房子 —— 动态规划入门详解
算法·动态规划
CV-Climber12 小时前
检索技术的实际应用
人工智能·算法
hhzz13 小时前
Tiger AI Platform平台中增加人脸识别功能
图像处理·人工智能·算法·计算机视觉·大模型
从零开始的代码生活_13 小时前
C++ 继承详解:访问控制、对象模型、菱形继承与设计取舍
开发语言·c++·后端·学习·算法