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 这个三元组。为了避免这种情况,要跳过这些相同的元素

相关推荐
乐观勇敢坚强的老彭33 分钟前
C++ 竞赛常用算法模板速查表
开发语言·c++·算法
Dr.kangder35 分钟前
嵌入式面试总结(十六)——AMBA总线
面试·职场和发展·架构·嵌入式·虚拟化·总线
高洁0138 分钟前
工信部教考中心证书
人工智能·深度学习·算法·机器学习·知识图谱
我变成萤火虫1 小时前
河南萌新联赛2026第(三)场:郑州轻工业大学
数据结构·c++·算法·贪心算法·stl·深度优先·哈希算法
Dr.kangder1 小时前
嵌入式面试总结(十九)——内存泄露
单片机·算法·面试·职场和发展·架构·硬件架构
Dr.kangder1 小时前
嵌入式面试总结(十七)——DMA总线
面试·职场和发展·架构·嵌入式·总线
Herbert_hwt1 小时前
【C语言基础】常量、选择结构与运算符全解析
c语言·开发语言·算法
Suxing92 小时前
C语言基础分享:从“租房”到“拆迁”,C语言动态内存管理
java·数据结构·算法
LuminousCPP2 小时前
单链表专题(四)-刷题复盘篇-LeetCode 138 随机链表复制|原地拷贝法突破复杂指针操作
数据结构·笔记·算法·leetcode·链表
逆境不可逃3 小时前
【LeetCode 912】排序数组——随机化快速排序详解
数据结构·算法·排序算法