当前位置: 首页 > news >正文

LeetCode 热题100 15. 三数之和

LeetCode 热题100 | 15. 三数之和

大家好,今天我们来解决一道经典的算法题——三数之和。这道题在 LeetCode 上被标记为中等难度,要求我们从一个整数数组中找到所有不重复的三元组,使得三元组的和为 0。下面我将详细讲解解题思路,并附上 Python 代码实现。


题目描述

给定一个整数数组 nums,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != kj != k,同时还满足 nums[i] + nums[j] + nums[k] == 0。请你返回所有和为 0 且不重复的三元组。

示例:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]

解题思路

这道题的核心是找到所有满足条件的三元组,同时避免重复。我们可以通过排序数组和双指针法来高效地解决这个问题。

核心思想
  1. 排序数组

    • 将数组排序,方便后续使用双指针法。
  2. 遍历数组

    • 固定一个数 nums[i],然后在剩下的数组中使用双指针法寻找两个数 nums[left]nums[right],使得 nums[i] + nums[left] + nums[right] == 0
  3. 双指针法

    • 初始化 left = i + 1right = len(nums) - 1
    • 如果 nums[i] + nums[left] + nums[right] < 0,则 left 右移。
    • 如果 nums[i] + nums[left] + nums[right] > 0,则 right 左移。
    • 如果 nums[i] + nums[left] + nums[right] == 0,则找到一个三元组,记录下来,并跳过重复的元素。
  4. 去重

    • 在遍历过程中,跳过重复的 nums[i]nums[left]nums[right],避免重复的三元组。

代码实现

def threeSum(nums):
    """
    :type nums: List[int]
    :rtype: List[List[int]]
    """
    nums.sort()  # 排序数组
    result = []  # 存储结果
    
    for i in range(len(nums) - 2):  # 遍历数组,固定 nums[i]
        if i > 0 and nums[i] == nums[i - 1]:  # 跳过重复的 nums[i]
            continue
        
        left, right = i + 1, len(nums) - 1  # 初始化双指针
        while left < right:
            total = nums[i] + nums[left] + nums[right]  # 计算三数之和
            if total < 0:
                left += 1  # 和小于 0,左指针右移
            elif total > 0:
                right -= 1  # 和大于 0,右指针左移
            else:
                result.append([nums[i], nums[left], nums[right]])  # 找到一个三元组
                # 跳过重复的 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
    
    return result

代码解析

  1. 排序数组

    • 将数组排序,方便后续使用双指针法。
  2. 遍历数组

    • 固定一个数 nums[i],然后在剩下的数组中使用双指针法寻找两个数 nums[left]nums[right]
  3. 双指针法

    • 初始化 left = i + 1right = len(nums) - 1
    • 根据三数之和的大小,移动 leftright 指针。
  4. 去重

    • 在遍历过程中,跳过重复的 nums[i]nums[left]nums[right],避免重复的三元组。

复杂度分析

  • 时间复杂度:O(n²),其中 n 是数组的长度。排序的时间复杂度为 O(n log n),双指针法的时间复杂度为 O(n²)。
  • 空间复杂度:O(1),只使用了常数个额外空间。

示例运行

示例 1
# 输入:nums = [-1,0,1,2,-1,-4]
nums = [-1, 0, 1, 2, -1, -4]
print(threeSum(nums))  # 输出: [[-1, -1, 2], [-1, 0, 1]]
示例 2
# 输入:nums = [0,1,1]
nums = [0, 1, 1]
print(threeSum(nums))  # 输出: []
示例 3
# 输入:nums = [0,0,0]
nums = [0, 0, 0]
print(threeSum(nums))  # 输出: [[0, 0, 0]]

总结

通过排序数组和双指针法,我们可以高效地找到所有满足条件的三元组,并避免重复。这种方法的时间复杂度为 O(n²),能够处理较大的输入规模。希望这篇题解对你有帮助!如果还有其他问题,欢迎继续提问!

关注我,获取更多算法题解和编程技巧!

相关文章:

  • 宿主机的 root 是否等于 Docker 容器的 root?
  • C++的异步相关操作
  • YOLOv10 解析与地平线 征程 6 模型量化
  • 多线程基础系列-线程池
  • 洛谷 P8705:[蓝桥杯 2020 省 B1] 填空题之“试题 E :矩阵” ← 卡特兰数
  • 322.零钱兑换
  • Go语言--语法基础2--下载安装
  • AF3 DataPipeline类process_multiseq_fasta 方法解读
  • [数据结构笔记] 1. 顺序表 内含所有函数C语言代码,完全无伪代码
  • 使用串口工具实现tcp与udp收发
  • Leetcode2717:半有序排列
  • 【原创工具】同文件夹PDF文件合并 By怜渠客
  • 安全见闻4
  • 多功能免费网络测速及问题诊断工具
  • 【C++】:STL详解 —— vector类
  • C++知识整理day9——继承(基类与派生类之间的转换、派生类的默认成员函数、多继承问题)
  • Linux(Centos 7.6)命令详解:uniq
  • 【愚公系列】《Python网络爬虫从入门到精通》034-DataFrame简单数据计算整理
  • 表单制作代码,登录动画背景前端模板
  • 2025网络安全等级测评报告,信息安全风险评估报告(Word模板)
  • 至尊传奇手游官方正版下载/娄底seo
  • 德州网站建设/国内10大搜索引擎
  • 北京建网站费用/美区下载的app怎么更新
  • 城乡与住房建设厅网站/网络推广方式方法
  • 关于网站建设的电话销售话术/电商运营公司
  • 做网站用新域名还是老域名/关键词优化报价推荐