基础数据结构之数组的双指针技巧之对撞指针(两端向中间):三数之和(LeetCode 15 中等题)

**题目:**给你一个整数数组 nums ,判断是否存在三元组 nums\[i, numsj, numsk] 满足 i != j、i != k 且 j != k ,同时还满足 numsi + numsj + numsk == 0 。请你返回所有和为 0 且不重复的三元组。

**解题思路:**三层循环暴力法会得到重复结果,所以需要先排序去除重复。

双指针对撞也需要先排序,之后先固定一个初始值,之后需要俩数字和初始值结合起来为0,俩数字如何选择?可以通过第一个数字和最后一个数字加起来看跟目标值的对比,大了说明需要变小一点,那就移动大数那边的指针,否则,就移动小数那边的指针。其中,边界条件需要考虑:初始值一致或者双指针对应的俩数字跟相邻数字一致的话都会导致出现重复结果,需要进行排除。

python 复制代码
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        # 预处理:先排序,避免三个值一致但顺序不同的情况出现
        nums.sort()
        result = []
        n = len(nums)
        for i in range(0,n-2):
            # 边界处理:i值一样的也需要跳过(已经处理过则跳过)
            if nums[i] == nums[i-1] and i > 0:
                continue
            # 先确定一个数,剩下两个数分别头尾指针开始对撞。根据和的大小决定哪个指针移动
            j = i + 1
            k = n - 1
            while j < k:
                target = nums[i]+nums[j]+nums[k]
                if target == 0:
                    result.append([nums[i],nums[j],nums[k]])
                    # 边界处理:j、k两侧一致的元素需要跳过(已经处理过则跳过)
                    while j < k and nums[j] == nums[j+1]:
                        j+=1
                    while j < k and nums[k] == nums[k-1]:
                        k-=1
                    # 同时移动前需要排除大小一致的元素,避免结果重复
                    j+=1
                    k-=1
                elif j < k and target<0:
                    j+=1
                elif j < k and target>0:
                    k-=1
                
        return result
相关推荐
飞Link12 小时前
什么是 AirSim?一文读懂无人机仿真平台
python·算法·无人机
一去不复返的通信er15 小时前
贪心算法-合并区间(LeetCode 56)
算法·leetcode·贪心算法
Shaoshing15 小时前
LeetCode100 49. 字母异位词分组
java·算法
YFJ_mily15 小时前
第二届区块链技术与基础模型国际学术会议(BTFM2027)
算法·区块链·能源·智能系统·rdlink研发家·机器人自动化
汤姆宝库16 小时前
收官深拆:第一性原理、产业电网与未来推演
大数据·人工智能·算法
moshuying18 小时前
块扩散 + GDN 改造:Clover 把「并行生成」塞进了 Agent 的长上下文里
前端·算法
没落之王18 小时前
历史系统建模:宋初太祖太宗「再立天庭」秩序重构推演
人工智能·算法·重构
INGNIGHT19 小时前
91 · 最小调整代价(序列dp)
数据结构·算法·leetcode
moshuying19 小时前
扩散模型开始写代码、开网页了:350 亿参数,速度比 Jev 快一倍
前端·算法