青铜三人行之两数之和
先说一个消息,为了方便互相交流学习,青铜三人行建了个微信群,感兴趣的伙伴可以扫码加下面的小助手抱你入群哦!
哈喽,大家好,欢迎来到青铜三人行的每周一题现场。在接下来的时间里,我们三人(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 的网站找到题目先刷一遍,并与我们或者身边的小伙伴们分享你的思路~
下周见!
三人行
- 知乎专栏
- 视频专辑
青铜三人行之两数之和相关推荐
- 【每日一算法】两数之和 IV - 输入 BST
微信改版,加星标不迷路! 每日一算法-两数之和IV-输入BST 作者:阿广 阅读目录 1 题目 2 解析 1 题目 给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目 ...
- java 1099_【LeetCode(Java) - 1099】小于 K 的两数之和
[LeetCode(Java) - 1099]小于 K 的两数之和 [LeetCode(Java) - 1099]小于 K 的两数之和 文章目录 1.题目描述 2.解题思路 3.解题代码 1.题目描述 ...
- Leetcode刷题第1题:两数之和(基于Java语言)
** Leetcode刷题第1题:两数之和(基于Java语言) ** 题目: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标 ...
- 【前端来刷LeetCode】两数之和与两数相加
大部分玩前端的小伙伴,在算法上都相对要薄弱些,毕竟调样式.调兼容就够掉头发的了,哪还有多余的头发再去折腾. 确实在前端中需要使用到算法的地方是比较少,但若要往高级方向发展,算法的基本功就非常重要啦.对 ...
- leetCode:twoSum 两数之和 【JAVA实现】
LeetCode 两数之和 给定一个整数数组,返回两个数字的索引,使它们相加到特定目标. 您可以假设每个输入只有一个解决方案,并且您可能不会两次使用相同的元素. 更多文章查看个人博客 个人博客地址:t ...
- LintCode-56.两数之和
两数之和 给一个整数数组,找到两个数使得他们的和等于一个给定的数 target. 你需要实现的函数twoSum需要返回这两个数的下标, 并且第一个下标小于第二个下标.注意这里下标的范围是 1 到 n, ...
- 【算法】哈希表 ( 两数之和 )
算法 系列博客 [算法]刷题范围建议 和 代码规范 [算法]复杂度理论 ( 时间复杂度 ) [字符串]最长回文子串 ( 蛮力算法 ) [字符串]最长回文子串 ( 中心线枚举算法 ) [字符串]最长回文 ...
- leetcode 两数之和 整数反转 回文数 罗马数字转整数
1.两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个 ...
- 【leetcode】 算法题1 两数之和
[leetcode] 算法题1 两数之和 问题 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums ...
最新文章
- c4d+ps打造抽象NFT加密艺术 Create Abstract NFT Crypto Art with Cinema 4D + Photoshop
- 自定义RadioGrop,支持添加包裹着的RadioButton
- linux下mkdir头文件_整理Linux下gcc编译中关于头文件与库文件搜索路径相关问题
- 算法提高课-图论-欧拉回路和欧拉路径-AcWing 1185. 单词游戏:判断有向图是否存在欧拉路径、并查集
- response.setStatus的时机
- 关于textarea的ie9的maxlength不起作用的问题,请参考如下URL解决。
- /etc/sysconfig/i18n文件详解
- c++11中的for简化用法
- 网络 传输层 | UDP协议与TCP协议详解(三次握手及四次挥手、滑动窗口、拥塞控制)
- 最新增值税商品税目编码表_姓名:增值税,税率:13%,9%,6%,这是我最新最全税率表!...
- 8、技术分析fastJson使用
- 数据科学包3-pandas快速入门2
- noip2017颓废记
- EtherCAT运动控制器的PLC编程(一) 直线插补
- SQL中drop,delete和truncate的异同
- 二进制十进制十六进制转换_二进制数制到十进制数制的转换
- IIC(I2C)总线设备地址,例如E2PROM、CH455G等器件应用
- 【笨木头Unity】入门之旅007:Demo之四处找死(二)_主角移动和旋转
- 关于scanf与scanf_s
- Java实现数组列项相加_裂项求和法 - osc_rkun22vq的个人空间 - OSCHINA - 中文开源技术交流社区...