先说一个消息,为了方便互相交流学习,青铜三人行建了个微信群,感兴趣的伙伴可以扫码加下面的小助手抱你入群哦!

哈喽,大家好,欢迎来到青铜三人行的每周一题现场。在接下来的时间里,我们三人(Helen、书香、曾大师)会在每周选择一道编程算法题来完成,和大家一起探讨一下解题的思路。所谓每周一题,代码无敌,欢迎各位小伙伴们一起进入我们的刷题之旅~

两数之和

青铜三人行——每周一题@两数之和

力扣题目​

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

//给定 nums = [2, 7, 11, 15], target = 9
//因为 nums[0] + nums[1] = 2 + 7 = 9
//所以返回 [0, 1]

解法一

拿到题目,Helen 心想,这次题目难道不大。略一思忖,要在数组中找到满足某个条件的两个数,一个双重循环搞定即可:

function twoSum(num, target) {for (const index in num) {for (const _index in num) {if (index !== _index && num[index] + num[_index] === target) {return [index, _index];}}}
}
​
//作者:Helen
//链接:https://leetcode-cn.com/circle/discuss/5cC2dU/view/p3MA3g/
//来源:力扣(LeetCode)
//著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


顺利通过题目!但是效率似乎并不理想…

解法二

接下来就要优化算法,Helen 审视代码,发觉影响效率的主要原因恐怕是在于双重循环所造成的 O(n²) 复杂度。要想提高效率,恐怕就要在一重循环里搞定题目。但如何在一次迭代中找到两个数的关系呢?确实颇费考虑… 算法领域中,空间与时间通常如同鱼和熊掌一般不可兼得。空间换时间…Helen 灵光一现,对了,一次迭代中表现两个数的关系,可以在 map 结构中用查找 key 的方式呀。考虑至此,信手写出了第二版代码:

function twoSum(nums, target) {const numsMap = {};for (const index in nums) {numsMap[nums[index]] = index;}for (const index in nums) {const complement = target - nums[index];if (numsMap[complement] && numsMap[complement] !== index) {return [index, numsMap[complement]];}}
}
​
//作者:Helen
//链接:https://leetcode-cn.com/circle/discuss/5cC2dU/view/p3MA3g/
//来源:力扣(LeetCode)
//著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

如此一来,时间复杂度减为 O(n), 速度果然大大提高:

书香作为一个函数式编程的拥护者,平日里对 map, filter, reduce 等方法都记在心里。看到这个代码,心想恐怕在循环中对数组的频繁引用是一个可以优化的点,于是利用 JavaScript 中内置的 reduce 方法稍作修改:

const twoSum = function(nums, target) {const objNums = nums.reduce((acc, num,index) => {acc[num]=index; return acc},{});
​for (let i=0; i<nums.length;i++) {const num = nums[i];const other = objNums[target-num];if(other!==undefined && other!==i){return [i,other]}}return;
};
​
//作者:demongodYY
//链接:https://leetcode-cn.com/circle/discuss/5cC2dU/view/8eOrHo/
//来源:力扣(LeetCode)
//著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

时间和空间上居然都有所提高,看来 JavaScript 对内置方法的优化果然到位:

解法三

于此同时,Helen 则进一步对代码进行了优化。题目要求只需要找到满足条件的两个数,那么有可能在没有遍历完的时候就能找到呀。如此一来,就不必提前将整个数组转换成 map 结构,而是边转换边查找,在找到满足条件的时候即可返回:

function twoSum(nums, target) {const numsMap = {};for (const index in nums) {const complement = target - nums[index];if (numsMap[complement]) {return [ index, numsMap[complement]];}numsMap[nums[index]] = index;}
}
​
//作者:Helen
//链接:https://leetcode-cn.com/circle/discuss/5cC2dU/view/p3MA3g/
//来源:力扣(LeetCode)
//著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

如此一来,代码性能大大地得到了优化:

extra

最后,由曾大师为我们在 go 语言中展现了一把对内存的极致管理,也体现了对于不同编程语言特性的优化差别:

func twoSum(nums []int, target int) []int {for i := 0; i < len(nums); i++ { for j := i+1; j < len(nums); j++ {if nums[i]+nums[j] == target {return []int{i,j}}}}return []int{}
}
​
//作者:glowd
//链接:https://leetcode-cn.com/circle/discuss/5cC2dU/view/omqRef/
//来源:力扣(LeetCode)
//著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

天啊,内存消耗仅为 2.9MB,在所有 Go 提交中击败了 100% 的用户!

结尾

OK,这就是咱们青铜三人行的第一次分享的全部内容啦,虽然很多地方还不完善,但也希望凭借一点微薄的力量,提起大家对编程算法题的兴趣。

如果看到了这次分享,你有一些灵感的话,请立即拿起手中的键盘,打开 leetcode 的网站找到题目先刷一遍,并与我们或者身边的小伙伴们分享你的思路~

下周见!


三人行

  • 知乎专栏
  • 视频专辑

青铜三人行之两数之和相关推荐

  1. 【每日一算法】两数之和 IV - 输入 BST

    微信改版,加星标不迷路! 每日一算法-两数之和IV-输入BST 作者:阿广 阅读目录 1 题目 2 解析 1 题目 给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目 ...

  2. java 1099_【LeetCode(Java) - 1099】小于 K 的两数之和

    [LeetCode(Java) - 1099]小于 K 的两数之和 [LeetCode(Java) - 1099]小于 K 的两数之和 文章目录 1.题目描述 2.解题思路 3.解题代码 1.题目描述 ...

  3. Leetcode刷题第1题:两数之和(基于Java语言)

    ** Leetcode刷题第1题:两数之和(基于Java语言) ** 题目: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标 ...

  4. 【前端来刷LeetCode】两数之和与两数相加

    大部分玩前端的小伙伴,在算法上都相对要薄弱些,毕竟调样式.调兼容就够掉头发的了,哪还有多余的头发再去折腾. 确实在前端中需要使用到算法的地方是比较少,但若要往高级方向发展,算法的基本功就非常重要啦.对 ...

  5. leetCode:twoSum 两数之和 【JAVA实现】

    LeetCode 两数之和 给定一个整数数组,返回两个数字的索引,使它们相加到特定目标. 您可以假设每个输入只有一个解决方案,并且您可能不会两次使用相同的元素. 更多文章查看个人博客 个人博客地址:t ...

  6. LintCode-56.两数之和

    两数之和 给一个整数数组,找到两个数使得他们的和等于一个给定的数 target. 你需要实现的函数twoSum需要返回这两个数的下标, 并且第一个下标小于第二个下标.注意这里下标的范围是 1 到 n, ...

  7. 【算法】哈希表 ( 两数之和 )

    算法 系列博客 [算法]刷题范围建议 和 代码规范 [算法]复杂度理论 ( 时间复杂度 ) [字符串]最长回文子串 ( 蛮力算法 ) [字符串]最长回文子串 ( 中心线枚举算法 ) [字符串]最长回文 ...

  8. leetcode 两数之和 整数反转 回文数 罗马数字转整数

    1.两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个 ...

  9. 【leetcode】 算法题1 两数之和

    [leetcode] 算法题1 两数之和 问题   给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums ...

最新文章

  1. c4d+ps打造抽象NFT加密艺术 Create Abstract NFT Crypto Art with Cinema 4D + Photoshop
  2. 自定义RadioGrop,支持添加包裹着的RadioButton
  3. linux下mkdir头文件_整理Linux下gcc编译中关于头文件与库文件搜索路径相关问题
  4. 算法提高课-图论-欧拉回路和欧拉路径-AcWing 1185. 单词游戏:判断有向图是否存在欧拉路径、并查集
  5. response.setStatus的时机
  6. 关于textarea的ie9的maxlength不起作用的问题,请参考如下URL解决。
  7. /etc/sysconfig/i18n文件详解
  8. c++11中的for简化用法
  9. 网络 传输层 | UDP协议与TCP协议详解(三次握手及四次挥手、滑动窗口、拥塞控制)
  10. 最新增值税商品税目编码表_姓名:增值税,税率:13%,9%,6%,这是我最新最全税率表!...
  11. 8、技术分析fastJson使用
  12. 数据科学包3-pandas快速入门2
  13. noip2017颓废记
  14. EtherCAT运动控制器的PLC编程(一) 直线插补
  15. SQL中drop,delete和truncate的异同
  16. 二进制十进制十六进制转换_二进制数制到十进制数制的转换
  17. IIC(I2C)总线设备地址,例如E2PROM、CH455G等器件应用
  18. 【笨木头Unity】入门之旅007:Demo之四处找死(二)_主角移动和旋转
  19. 关于scanf与scanf_s
  20. Java实现数组列项相加_裂项求和法 - osc_rkun22vq的个人空间 - OSCHINA - 中文开源技术交流社区...

热门文章

  1. 联邦学习(Federated Learning)概述
  2. HTML|文本框和单选框
  3. [NVIDIA jetson nano 初体验避坑指南。镜像烧录、换源、中文输入法、打开PWM风扇汇总(持续更新)
  4. 【离散数学】图论-思维导图
  5. Shell 的string 操作
  6. js websocket断线重连
  7. 三菱伺服MR-J2S-20A 伺服驱动与编码器接线
  8. 简单总结笔试和面试中的海量数据问题
  9. MySQL 数据库表的设计
  10. 笔记本触摸板失灵修复小技巧_想恢复图片原来的背景?PS修复操作小技巧