张小明 2025/12/19 16:42:08
山东网站备案注意事项,网站开发有哪几类,网站产品 模块,餐饮网站模板三数之和#xff1a;从 “暴力狂” 到 “双指针大师” 的修炼之路 #x1f680;
一、LeetCode 第 15 题#xff1a;三数之和
先来看看LeetCode上给出的题目描述#xff1a;
给你一个整数数组 nums #xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、…三数之和从 “暴力狂” 到 “双指针大师” 的修炼之路 一、LeetCode 第 15 题三数之和先来看看LeetCode上给出的题目描述给你一个整数数组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-105 nums[i] 105是不是看起来有点绕别急咱们从简单的开始盘一步步搞定这个 “磨人小妖精”二、回顾两数之和小试牛刀的开胃菜 在啃 “三数之和” 这块硬骨头前必须先回味一下前面学过的 —— 两数之和。1、暴力拆解简单但 “费时间” 的莽夫做法 两数之和要找两个数加起来等于目标值暴力法的思路特直接拿每个数跟它后面的数挨个配对看和是不是目标值。代码长这样javascriptfunction twoSum(nums, target) { for (let i 0; i nums.length; i) { for (let j i 1; j nums.length; j) { if (nums[i] nums[j] target) { return [i, j]; } } } return []; }这方法时间复杂度是 O (n²)就像在操场找两个人挨个问 “你们俩加起来够不够 100 斤”人多了真扛不住2、hashMap 求差用空间换时间的 “小聪明” 既然暴力法太费时间咱换个思路用哈希表存下每个数的位置然后对每个数nums[i]直接算target - nums[i]是不是在哈希表里。代码示例javascriptfunction twoSum(nums, target) { const map new Map(); for (let i 0; i nums.length; i) { const complement target - nums[i]; if (map.has(complement)) { return [map.get(complement), i]; } map.set(nums[i], i); } return []; }这招时间复杂度降到 O (n)空间复杂度 O (n)相当于给每个人发个名牌找的时候直接按名字喊效率瞬间飙升想要具体学习两数之和问题的同学可以看看我前面的文章https://blog.csdn.net/2302_80706750/article/details/155208999?spm1001.2014.3001.5501。三、三数之和升级打怪的正餐时间 两数之和搞定了三数之和怎么搞别急咱们先从 “莽夫” 开始再进化成 “智者”。1、暴力拆解三重循环的 “时间杀手” ⏳最直接的想法三个数嘛那就三重循环挨个试代码大概长这样javascriptfunction threeSum(nums) { const res []; const len nums.length; // 先排序方便去重虽然暴力法去重麻烦但先排个序看着舒服 nums.sort((a, b) a - b); for (let i 0; i len - 2; i) { // 跳过重复的i暴力法去重的雏形 if (i 0 nums[i] nums[i - 1]) continue; for (let j i 1; j len - 1; j) { if (j i 1 nums[j] nums[j - 1]) continue; for (let k j 1; k len; k) { if (k j 1 nums[k] nums[k - 1]) continue; if (nums[i] nums[j] nums[k] 0) { res.push([nums[i], nums[j], nums[k]]); } } } } return res; }但这时间复杂度是 O (n³)想象一下如果数组有 1000 个元素那就是 10 亿次运算电脑看了都得哭 显然这招在 LeetCode 上是会超时的不能通过 LeetCode 必须换思路2、双指针解法排序 指针的 “黄金组合” 这才是解决三数之和的 “正道之光”核心思路是先排序再固定一个数剩下两个数用双指针找 —— 把三数问题降成两数问题妙啊1第一步排序排序排序重要的事说三遍为啥要排序因为排序后方便跳过重复元素重复的数挨在一起一眼就能看出来能让双指针 “有规律地移动”左边小右边大和大了就左移右指针和小了就右移左指针JavaScript 数组的sort()方法默认是按字符串排序的所以必须传个比较函数javascript// 升序排列从小到大a - b 0 时a在前b在后不交换 nums.sort((a, b) a - b); // 降序排列从大到小b - a 0 时b在前a在后不交换 // nums.sort((a, b) b - a);比如[2,3,2,1,4,9]排序后就成了[1,2,2,3,4,9]是不是清爽多了2第二步固定一个数派出 “左右护法” 指针固定一个起点i从 0 开始然后左指针left从i1出发右指针right从数组末尾出发三者形成 “铁三角”。3第三步根据三数之和 “指挥” 指针移动计算sum nums[i] nums[left] nums[right]如果sum 0完美加入结果集然后让left右移、right左移继续找下一组如果sum 0和太小了让left右移找个大点的数如果sum 0和太大了让right左移找个小点的数4第四步跳过重复元素拒绝 “复制粘贴”这是关键不然答案里会有重复的三元组对i如果nums[i] nums[i-1]说明和上一个起点一样直接跳过注意i 0才跳第一个元素不能跳对left找到一组解后left右移时如果和前一个数一样继续右移对right找到一组解后right左移时如果和后一个数一样继续左移5完整代码双指针的 “实战演练”javascriptfunction threeSum(nums) { // 先排序升序排列方便操作 nums.sort((a, b) a - b); const res []; // 固定i注意i最多到length-3因为要留left和right的位置 for (let i 0; i nums.length - 2; i) { // 跳过重复的起点i if (i 0 nums[i] nums[i - 1]) { continue; } // 左右指针left是i的下一个right是数组末尾 let left i 1; let right nums.length - 1; // 指针没相遇就继续找 while (left right) { const sum nums[i] nums[left] nums[right]; if (sum 0) { // 找到一组解加入结果 res.push([nums[i], nums[left], nums[right]]); // 移动指针继续找 left; right--; // 跳过重复的left while (left right nums[left] nums[left - 1]) { left; } // 跳过重复的right while (left right nums[right] nums[right 1]) { right--; } } else if (sum 0) { // 和太小left右移找大点的数 left; } else { // 和太大right左移找小点的数 right--; } } } return res; }这方法时间复杂度是 O (n²)排序占 O (nlogn)循环占 O (n²)空间复杂度 O (1) 或 O (n)取决于排序算法比暴力法可优雅太多了四、面试官可能会抛来的 “灵魂拷问” 为啥三数之和要先排序答排序不仅能方便去重重复元素挨在一起还能让双指针有规律地移动根据和的大小调整指针方向这是双指针解法的核心前提时间复杂度怎么算的答排序是 O (nlogn)外层循环 O (n)内层双指针循环 O (n)整体是 O (n²)比暴力法的 O (n³) 好太多啦去重逻辑为什么要那么写比如i 0才跳答因为i0是第一个元素前面没元素可比直接跳就错啦而i0时如果和前一个一样说明重复了必须跳否则会出现重复的三元组两数之和能用双指针吗三数之和为啥不用哈希表答两数之和用哈希表更简单O (n)双指针也能用但需要先排序O (nlogn)三数之和用哈希表去重太麻烦双指针配合排序去重更优雅所以选双指针五、结语从 “会做” 到 “做好” 的修行 ✨三数之和这道题从暴力法的 “蛮干” 到双指针的 “巧解”藏着一个很重要的编程思维把复杂问题拆解成简单问题再用合适的工具排序、指针优化。就像玩游戏新手只会平 A高手却会用技能连招 希望这篇文章能帮你搞懂三数之和的 “连招秘籍”下次遇到类似问题也能从容应对最后送大家一句话刷题不在多在于懂原理 —— 毕竟面试官要的不是 “做题机器”而是 “会思考的灵魂” 呀 加油未来的顶尖大佬们
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
自做建材配送网站外贸seo网站开发
ConfigMgr 使用与安全配置全解析 1. 常见环境问题理解 1.1 DNS 相关要点 在大型多区域环境中,可通过右键单击 DNS 服务器而非区域来启用和配置所有区域的清理功能。但需注意,此操作会影响所有区域,若需要按区域进行精细的清理设置,则不宜采用该方法。 在排查 DNS 问题时…
企业建网站的步骤室内设计软件自己设计
还在为Blender内置渲染器的物理精度不足而烦恼吗?Mitsuba-Blender插件为你提供了完美的解决方案。这款强大的集成工具将学术界公认的物理渲染器Mitsuba无缝融入Blender环境,让艺术家和研究人员都能享受到最前沿的渲染技术。🎯 【免费下载链接…
外贸网站推广如何做新任上海市领导调整公示
第一章:高危漏洞预警概述 在当前复杂的网络环境中,高危漏洞的爆发往往会在短时间内对全球范围内的信息系统造成严重威胁。及时发现并响应这些漏洞,是保障系统安全的核心环节。高危漏洞通常指那些可被远程利用、无需用户交互即可执行任意代码、…
办个网站需要多少钱如何查看一个网站做的外链
文|魏琳华编|王一粟年底似乎又到了AI厂商们展示实力的日子。上周,快手上演了一场为期五天的全能灵感周技术展示;本周,智谱的连续开源也如期而至。在这五天的时间内,快手带来了三个大模型、一个助力AI落地的…
如何做英文网站推广免费外链工具
01 生活哪有那么多弯弯绕, 无非是干饭香、躺平爽, 给自个儿整点儿乐子, 给朋友唠句玩笑。 忙到飞起不抓狂,闲下来不瞎慌, 鸡毛蒜皮的日子里, 怎么舒坦怎么浪~ 02 你瞎操心的事儿,八…