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

面试经典150题[029]:三数之和(LeetCode 15)

三数之和(LeetCode 15)

题目链接:三数之和(LeetCode 15)
难度:中等

1. 题目描述

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

注意:答案中不可以包含重复的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

示例 2:

输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。

示例 3:

输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。

要求:

  • 3 <= nums.length <= 3000
  • -10^5 <= nums[i] <= 10^5

2. 问题分析

2.1 规律

  • 问题本质是找三个不同索引的数之和为0,且结果不重复。
  • 暴力O(n^3)会超时,n=3000时太慢。
  • 核心问题:如何高效枚举三元组,同时避免重复?
  • 由于数组可能有重复元素,需要排序后跳过重复来去重。

2.2 排序 + 双指针思路

我们使用排序 + 双指针算法(时间O(n^2)):

  • 先对数组排序(O(n log n)),这样便于去重和使用双指针。
  • 遍历每个位置i(从0到n-3),固定nums[i]作为第一个数,目标是找nums[j] + nums[k] == -nums[i],其中j > i, k > j。
  • 跳过重复的nums[i](if i > 0 and nums[i] == nums[i-1]: continue),避免重复三元组。
  • 对于每个i,设置左指针l = i+1,右指针r = n-1。
  • 在[l, r]区间:
    • 如果nums[l] + nums[r] == -nums[i],添加三元组[l, i, r]到结果(注意排序后顺序是升序),然后l++,r–,并跳过重复的l和r。
    • 如果nums[l] + nums[r] < -nums[i],l++(增大和)。
    • 如果nums[l] + nums[r] > -nums[i],r–(减小和)。
  • 当l >= r时,结束当前i的搜索。
  • 特殊处理全0情况,会自然包含[[0,0,0]]。

这种方式确保每个三元组只被枚举一次,且不重复。

3. 代码实现

Python

class Solution:def threeSum(self, nums):n = len(nums)nums.sort()result = []for i in range(n - 2):# 跳过重复的 iif i > 0 and nums[i] == nums[i - 1]:continuel, r = i + 1, n - 1target = -nums[i]while l < r:total = nums[l] + nums[r]if total == target:result.append([nums[i], nums[l], nums[r]])# 跳过重复的 l 和 rwhile l < r and nums[l] == nums[l + 1]:l += 1while l < r and nums[r] == nums[r - 1]:r -= 1l += 1r -= 1elif total < target:l += 1else:r -= 1return result

C++

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {int n = nums.size();sort(nums.begin(), nums.end());vector<vector<int>> result;for (int i = 0; i < n - 2; ++i) {// 跳过重复的 iif (i > 0 && nums[i] == nums[i - 1]) {continue;}int l = i + 1, r = n - 1;int target = -nums[i];while (l < r) {int total = nums[l] + nums[r];if (total == target) {result.push_back({nums[i], nums[l], nums[r]});// 跳过重复的 l 和 rwhile (l < r && nums[l] == nums[l + 1]) {++l;}while (l < r && nums[r] == nums[r - 1]) {--r;}++l;--r;} else if (total < target) {++l;} else {--r;}}}return result;}
};

4. 复杂度分析

  • 时间复杂度:O(n^2),排序O(n log n) + 双指针O(n2),主导是O(n2)
  • 空间复杂度:O(1),忽略排序的临时空间和输出结果空间

5. 总结

  • 三数之和 + 不重复 → 排序 + 双指针是标准解法
  • 核心是固定一数 + 两指针求和,跳过重复确保唯一性
    • 可扩展到k数之和(用DFS或更优化)
    • 注意边界:n>=3,全0/全非0情况

复习

面试经典150题[014]:加油站(LeetCode 134)


文章转载自:

http://FPmOOtdo.zbqry.cn
http://wB7k8qXd.zbqry.cn
http://YgbiHgIA.zbqry.cn
http://t0w7l9pY.zbqry.cn
http://QgvLsflP.zbqry.cn
http://btvCqs5Z.zbqry.cn
http://l1WvPmSO.zbqry.cn
http://8zgPMsOh.zbqry.cn
http://52ABZabz.zbqry.cn
http://ik9KmvK2.zbqry.cn
http://RUt1Ecqi.zbqry.cn
http://qjGOnEHK.zbqry.cn
http://HK2ShxqF.zbqry.cn
http://4yNsgL9N.zbqry.cn
http://JAjvLkx3.zbqry.cn
http://L0qbTzR5.zbqry.cn
http://J4v64KWT.zbqry.cn
http://W6vNZzhU.zbqry.cn
http://8gBXaQTB.zbqry.cn
http://uDmr8yYT.zbqry.cn
http://DrhVvhlF.zbqry.cn
http://jNvcMjJK.zbqry.cn
http://iN7RNsmN.zbqry.cn
http://GOrVFVAd.zbqry.cn
http://RGeMjDu0.zbqry.cn
http://xJ2yTGiM.zbqry.cn
http://ec771sQC.zbqry.cn
http://QcPXuNRL.zbqry.cn
http://2LLC7I3F.zbqry.cn
http://fEkBSREQ.zbqry.cn
http://www.dtcms.com/a/379671.html

相关文章:

  • Ubuntu 24.04 搭建k8s 1.33.4
  • 从数字后端角度谈谈occ电路(一)
  • Hadoop简介:分布式系统的基石与核心架构详解
  • [数据结构] 优先级队列(堆)
  • 计算机毕业设计 基于深度学习的酒店评论文本情感分析研究 Python毕业设计项目 Hadoop毕业设计选题 机器学习选题【附源码+文档报告+安装调试】
  • 数据结构 Java对象的比较
  • EDID 数据结构解析与编辑工具:校验和计算、厂商/设备名编解码、物理地址读写、颜色与时序信息提取
  • 龙蜥8.10中spark各种集群及单机模式的搭建spark3.5.6(基于hadoop3.3.6集群)
  • Hadoop MapOutputBuffer:Map高性能核心揭秘
  • Kubernetes 弹性伸缩:深入讲解 HPA 和 VPA
  • 代理服务器是什么?怎么选择?
  • java Redisson 实现限流每秒/分钟/小时限制N个请求 -V2.0
  • 高并发、低延迟全球直播系统架构
  • zookeeper是啥
  • 短波红外相机在机器视觉检测方向的应用
  • 阿里云国际代理:如何利用RDS构建高可用、可扩展的数据库架构
  • 【Python】通俗理解反向传播
  • RFID技术在半导体电子货架上的应用方案
  • Windows 安装 Redis 教程
  • CMake 全流程开发实战:从零开始掌握C++项目构建、测试到一键分发的完整解决方案​
  • 如果数据量小但是点击后需要获取的是最新的定位信息,这种时候采取什么策略最优?
  • 使用 Pyinstaller 打包 PPOCRLabel
  • 科技信息差(9.12)
  • 是德科技 | 关于AI 数据中心时代的光通信的精选问答
  • 深入剖析 Elasticsearch (ES) 的近实时搜索原理
  • Qt5 | TCP服务器开源模板工程实战
  • 飞鹤财报“新解”:科技筑牢护城河,寒冬凸显龙头“硬核力”
  • 第6.2节 Android Agent开发<一>
  • 【 C/C++ 算法】入门动态规划-----一维动态规划基础(以练代学式)
  • YOLOv8 从yaml配置文件生成PyTorch模型