壹 ❀ 引

在学习算法基础的同时,我还是继续捡起leetcode的算法题了,珍惜时间,算法每天进步一点点。不得不说,在了解了一些算法概念后,至少有些答案是能看懂了......(惭愧)虽然我很菜,但是多写多练应该还是会有提升。那么这篇文章就从两数之和开始。

原题如下:

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

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9

所以返回 [0, 1]

请实现如下方法能达到上述效果:

/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) { };

贰 ❀ 听风是风不太聪明的实现

在解释优质答案前,我先说说自己的思路,毕竟不是很好的做法,大家也可以跳过不看。

我想出了两种做法,先说第一种,由于只有一个数组,但是我们得让数组中的元素两两相加并与目标值判断是否相等,所以首先想到就是利用for循环嵌套,遍历同一个数组。

由于不能重复使用同一个元素,所以外层从0开始遍历时,内层循环的索引起点肯定得是1,当外层是1时,内层索引从2开始。这样做的目的除了避免同一元素多次使用外,还减少了重复比较次数。我们来大致脑补下,比如外层是0时,会与内层1相加,而如果内层不在外层基础上加1,就还会出现外层是1时,与内层是0相加比较的情况,这样就重复了。

所以知道了这些就好做了,直接贴我的实现:

/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function (nums, target) {
// 用来装目标索引的空数组
var result = [],
len = nums.length;
for (var i = 0; i < len; i++) {
// 注意,这里从i+1开始遍历
for (var j = i + 1; j < len; j++) {
if (nums[i] + nums[j] === target) {
// 注意,concat返回一个新数组
result = result.concat(i, j);
return result;
};
};
}
};

我想到的第二种解决思路其实是在学插入排序时得到的灵感,上面的实现简单粗暴,无非就是把一个数组当两个用,第二种思路就是对同一个数组正序倒序同时遍历比较,当然也得使用循环嵌套。

比如外层循环从0开始,那么内层循环从length-1处倒序遍历,一直遍历到0前面一位,期间的元素分别与0的数字相加并与target比较:

直接贴我的第二种思路,由于还是使用了循环嵌套,所以耗时相比第一种也只是提升了一点点,但内存使用却大了不少,所以也不算很好的实现。

/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function (nums, target) {
var result = [],
len = nums.length;
for (var i = 0; i < len; i++) {
var len_ = len - 1;
// 倒序遍历,一直遍历到i的前一位
while (len_ > i) {
if (nums[i] + nums[len_] === target) {
result = result.concat(i, len_);
return result;
};
len_--;
};
};
};

叁 ❀ 优质解答

那么在说完我的弱智算法,来看看官方的优质解答,直接贴代码,我们再分析实现:

/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function (nums, target) {
var temp = [],
len = nums.length;
for (var i = 0; i < len; i++) {
var dif = target - nums[i];
if (temp[dif] != undefined) {
return [temp[dif], i];
};
temp[nums[i]] = i;
};
};

这个思路其实就是借助了哈希表,牺牲少量空间大大减少运行用时,毕竟只用了一次遍历。如果大家对于哈希表很陌生,还是很推荐大家先理解常用数据结构,我在从零开始的算法入门科普(二)一文中有通过图解简单科普哈希表的概念,只是在上述代码在哈希表存值时并未借助哈希函数。

通常来说哈希表常常用来存储key-value的数据,由于我们最终是要获取目标元素索引,所以代码实现中直接使用数组元素作为位置映射,用于存储当前元素索引。其次,巧妙通过var dif = target - nums[i]分别获取目标值与当前遍历元素的差值,如果这个差值作为哈希表的索引能访问到有效元素,那么说明当前遍历的i与temp[dif](拿到的是元素在nums中的索引)就是要找的索引。

不看答案我是真的想不上去,表示惊呆了,那么关于两数之和就说到这了,收获很大!!!

本文结束!

2020.5.24复习,与哈希表思路相同,不过这次换成了字典,执行时间会略微提升,代码如下:

/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function (nums, target) {
var i = 0,
len = nums.length,
dict = {};
for (; i < len; i++) {
var dif = target - nums[i];
if (dif in dict) {
return [dict[dif], i];
};
dict[nums[i]] = i;
};
};

JS leetcode 两数之和解答思路分析的更多相关文章

  1. 【数据结构】Hash表简介及leetcode两数之和python实现

    文章目录 Hash表简介 基本思想 建立步骤 问题 Hash表实现 Hash函数构造 冲突处理方法 leetcode两数之和python实现 题目描述 基于Hash思想的实现 Hash表简介 基本思想 ...

  2. LeetCode两数之和

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

  3. leetcode - 两数之和Ⅳ 输入BST(653)

    题目描述:给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true. 解题思路:根据二叉搜索树的特点,对二叉搜索树进行中序遍历可以得到一个从小到达排 ...

  4. Leetcode -- 两数之和Ⅰ

    1. 两数之和 题目描述:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标. 示例:给定 nums = [2, 7, 11, 15 ...

  5. leetcode两数之和go语言

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

  6. C++ undered_map哈希表用法——leetcode两数之和

    undered_map 头文件:#include<undered_map> 创建表undered_map<key,value> Map_name; 插入元素 a[key]=va ...

  7. leetcode 两数之和 python

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

  8. 2021/9/26 Leetcode 两数之和

    题目:给你两个整数 a 和 b ,不使用 运算符 + 和 - ​​​​​​​,计算并返回两整数之和. int getSum(int a, int b) { while(b != 0){ unsigne ...

  9. leetcode 两数之和 II - 输入有序数组

    给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数. 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2. 说明: 返回的下标值 ...

  10. Leetcode 两数之和 (散列表)

    给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 15], target ...

随机推荐

  1. appium(三)使用方法

    一.appium环境搭建(先决条件) 1.安装JDk 2.安装SDK 参考文章:https://www.cnblogs.com/mrwhite2020/p/13160994.html 3.安装appn ...

  2. 机器学习-决策树系列-GBDT算法-集成学习-30

    目录 1. 复习 2. GBDT 3. gbdt应用于二分类: 3. gbdt应用于多类 4. 叶子节点输出值c的计算 5. GBDT的其他应用 6. GBDT+LR 代码实现 1. 复习 再开始学习 ...

  3. 面向对象SOLID原则-设计模式-第2篇

    面向对象设计的SOLID原则 1.开放封闭原则 一个软件实体 (类,函数,模块) 对扩展开放,对修改关闭.也就是 软件实体 应该尽量在不修改原有代码的情况下 进行扩展 举个例子, 装饰器的使用,就可以 ...

  4. [转帖]mysql - 使用文件中的 mysql 加载数据格式化 csv 日期列

    https://www.coder.work/article/2481907#:~:text=LOAD%20DATA%20INFILE%20%27%2Finvoices%2Finvoice138130 ...

  5. [转帖]PostgreSQL 10.0 preview 功能增强 - 国际化功能增强,支持ICU(International Components for Unicode)

    https://developer.aliyun.com/article/72935 标签 PostgreSQL , 10.0 , International Components for Unico ...

  6. [转帖]FIO使用说明

    FIO介绍: FIO是测试IOPS的非常好的工具,用来对磁盘进行压力测试和验证.磁盘IO是检查磁盘性能的重要指标,可以按照负载情况分成照顺序读写,随机读写两大类.FIO是一个可以产生很多线程或进程并执 ...

  7. [转帖]如何部署windows版本的oswatcher

    2017-02-22 没有评论 windows上也有os watcher:OSWFW. 目前支持的windows版本是: Windows XP (x86 & x64)Windows 7 (x8 ...

  8. [转帖]configure: error: cannot guess build type;you must specify one

    该问题一般出现在国产平台,从错误描述来看,意思是:无法猜测build类型,你必须指定一个. 解决办法: 1. 在系统/usr路径下搜索 config.guess 和 config.sub 这两个文件. ...

  9. [转帖]Linux中./configure、make、make install命令详解

    简单来说,make 是编译,make install 是安装.   总结:linux编译安装中configure.make和make install各自的作用  • ./configure是用来检测你 ...

  10. [转帖]记录一次spring-boot程序内存泄露排查

    现象 spring boot项目jvm启动配置-Xms4g -Xmx4g,然而很不幸的是程序所占的内存越来越高,都达到了12个多G,只能临时重启服务 常用命令 jstat -class PID jst ...