基础数据结构之数组的双指针技巧之对撞指针(两端向中间):三数之和(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
相关推荐
稚南城才子,乌衣巷风流40 分钟前
ST 表(Sparse Table)算法详解:原理、实现与应用
算法
hold?fish:palm1 小时前
9 找到字符串中所有字母异位词
c++·算法·leetcode
Sw1zzle1 小时前
算法入门(六):贪心算法 - 基础入门(Leetcode 121/455/860/376/738)
算法·leetcode·贪心算法
青山木1 小时前
Hot 100 --- 岛屿数量
java·数据结构·算法·leetcode·深度优先·广度优先
不会就选b2 小时前
算法日常・每日刷题--<归并排序>1
数据结构·算法
危桥带雨2 小时前
排序算法(快排、归并、计数、基数排序)
数据结构·算法·排序算法
啦啦啦啦啦zzzz2 小时前
算法:回溯算法
c++·算法·leetcode
IT探索2 小时前
Linux 查找文件指令总结
linux·算法
zephyr053 小时前
数据结构-并查集
数据结构