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

力扣hot100:三数之和(排序 + 双指针法)(15)

题目描述

解题思路

通过 排序 + 双指针 高效解决:

  1. 排序预处理:将数组升序排序,便于后续去重和双指针操作
  2. 固定第一个数:遍历数组,固定当前数字 nums[i] 作为三元组的第一个元素
  3. 双指针搜索
    • 左指针 left = i+1,右指针 right = len-1
    • 计算目标值:target = -nums[i]
    • 移动左右指针:
      • 若 nums[left] + nums[right] == target → 找到一组解
      • 若和小于 target → 左指针右移(增大数值)
      • 若和大于 target → 右指针左移(减小数值)
  4. 关键去重
    • 跳过重复的 nums[i](固定值去重)
    • 找到解后跳过重复的 nums[left] 和 nums[right](双指针去重)
代码实现
public List<List<Integer>> threeSum(int[] nums) {Arrays.sort(nums);int length=nums.length;List<List<Integer>> result=new ArrayList<>();for(int i=0;i<length;i++){if(i>0&&nums[i]==nums[i-1]){continue;}int left=i+1;int right=length-1;int target=0-nums[i];while(left<right){if(nums[left]+nums[right]==target){result.add(List.of(nums[i],nums[left],nums[right]));left++;right--;while(left<right&&nums[left]==nums[left-1]){left++;}while(left<right&&nums[right]==nums[right+1]){right--;}}else if(nums[left]+nums[right]<target){left++;}else{right--;}}}return result;}
算法解析
  1. 排序预处理(时间复杂度 O(n logn))

    • 使相同数字相邻,便于后续去重操作
    • 使双指针搜索成为可能(利用有序性)
  2. 固定值去重(关键步骤)

  • 确保相同的 nums[i] 只处理一次
  • 从 i>0 开始判断避免越界
  1. 双指针搜索(时间复杂度 O(n²))

    • 核心逻辑:固定 i 后,问题转化为两数之和问题
    • 指针移动
      • sum < target:左指针右移(增大数值)
      • sum > target:右指针左移(减小数值)
  2. 解去重处理(关键步骤)

  • 找到解后立即跳过重复的左右指针值
  • 确保不会记录重复的三元组
复杂度分析
  • 时间复杂度O(n²) 排序 O(n logn) + 双指针搜索 O(n²) → 主导项为 O(n²)
  • 空间复杂度O(1) 除结果集外,只使用常数级额外空间(排序占用 O(logn) 栈空间,不计入额外空间)
边界与陷阱
  1. 输入边界
    • 数组长度小于 3 直接返回空集
    • 全正数/全负数数组无解
  2. 去重时机
    • 固定值去重在 i 循环开始时
    • 双指针去重在找到解后立即执行
  3. 指针移动
    • 找到解后需同时移动双指针(不能只移一边)
总结与思考
  1. 排序是基础:有序数组才能使用双指针技巧
  2. 去重是关键:三重去重(固定值 + 左指针 + 右指针)缺一不可
  3. 双指针的威力:将 O(n³) 暴力解优化到 O(n²)
  4. 适用场景:多数 N 数之和问题可转化为双指针思路(如两数之和、四数之和)

学习建议:理解去重逻辑后,尝试解决 四数之和 巩固此方法!

http://www.dtcms.com/a/339909.html

相关文章:

  • 深度学习-167-MCP技术之工具函数的设计及注册到MCP服务器的两种方式
  • 零售行业新店网络零接触部署场景下,如何选择SDWAN
  • 排查Redis数据倾斜引发的性能瓶颈
  • 缓存-变更事件捕捉、更新策略、本地缓存和热key问题
  • Autoware Universe 感知模块详解 | 第零节 如何学习开源框架(以Autoware Universe为例)
  • 新手入门:用 LangChain+LlamaIndex 构建 RAG,通义千问 API 免费够用
  • 机器人控制基础:串级 PID 和模糊 PID介绍与对比(干货总结)
  • Java 大视界 -- Java 大数据在智能物流无人配送车路径规划与协同调度中的应用
  • [激光原理与应用-303]:光学设计 - 光路设计的输出件
  • Git#cherry-pick
  • 【C语言16天强化训练】从基础入门到进阶:Day 3
  • 光纤通信系统的光纤计量详解-连续测量更高效
  • Protobuf安装和使用
  • 把 AI 变成「图书馆管理员」——基于检索增强的离线图书语音导航小盒子
  • 更新一个GMT新增的投影类型:Spilhaus投影
  • 融智兴“RFID物流周转箱卡”荣获2025“IOTE 金奖”创新产品奖
  • 全0子数组的数目-子数组问题
  • 项目里程碑设定有哪些方法
  • 猫头虎AI分享|字节开源了一款具备长期记忆能力的多模态智能体:M3-Agent 下载、安装、配置、部署教程
  • Visual Studio 中文件属性(在解决方案资源管理器中选中文件,按 F4 或在右键菜单 -> 属性)
  • 【树莓派】【嵌入式】远程树莓派,解决ping不通问题
  • 第5.6节:awk字符串运算
  • python新工具-uv包管理工具
  • 编排之神--Kubernetes中的网络通信-Flannel插件及Calico插件演练
  • Android SystemServer 中 Service 的创建和启动方式
  • Milvus 安装和启动指南
  • 决策树学习(2)
  • almalinux9.6系统:k8s可选组件安装(1)
  • 数字ic后端设计从入门到精通14(含fusion compiler, tcl教学)半定制后端设计
  • 第三阶段数据库-2:数据库连接