壹 ❀ 引

在学习算法基础的同时,我还是继续捡起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. UEditor 添加在线管理图片删除功能 (转载)

    第一,需要添加一个 php 文件来实现删除功能,文件添加到: ueditor\php\action_delete.php 代码内容: <?php /*---------------------- ...

  2. [转帖]Linux 上 SQL Server 2022 (16.x) 的各版本和支持的功能

    https://zhuanlan.zhihu.com/p/371869456   本文内容 SQL Server 版本 将 SQL Server 用于客户端/服务器应用程序 SQL Server 组件 ...

  3. [转帖]如何监控Redis性能指标(译)

    Redis给人的印象是简单.很快,但是不代表它不需要关注它的性能指标,此文简单地介绍了一部分Redis性能指标.翻译过程中加入了自己延伸的一些疑问信息,仍然还有一些东西没有完全弄明白.原文中Metri ...

  4. 一个监控数据的思考-sockets_used

    一个监控数据的思考-sockets_used 背景 最近跟踪一个项目问题. Grafana的监控了里面有一个tcp的使用监控 CurrEstab 的数据量是: 700-2000 左右 但是同时有一个非 ...

  5. [转帖]k8s对接ceph,ceph-csi方式

    1.上传ceph-csi-yaml和ceph-csi-image 两个文件夹到服务器 2.加载 ceph-csi-image里面的镜像 3.将加载好的镜像上传到本地harbor上. 4.修改ceph- ...

  6. [转帖]JMeter压测Redis

    https://www.cnblogs.com/yjlch1016/p/14052402.html 一.Redis Data Set插件: https://jmeter-plugins.org/wik ...

  7. [转帖]021系统状态检测命令sosreport

    https://www.cnblogs.com/anyoneofus/p/16467677.html   sosreport命令用于收集系统配置及架构信息并输出诊断文档.

  8. 【转帖】32.MinorGC、MajorGC和FullGC的对比

    目录 1.MinorGC.MajorGC和FullGC的对比 2.GC触发机制 1.MinorGC.MajorGC和FullGC的对比 1.JVM在进行GC的时候,并不是每次都是对新生代.老年代.永久 ...

  9. Python学习之六_同时访问Oracle和Mysql的方法

    Python学习之六_同时访问Oracle和Mysql的方法 背景 jaydebeapi 可以访问大部分数据库. 但是他有一个问题是仅能够访问一种类型的数据库. 如果同事连接两种数据库,那么就会出现问 ...

  10. [转帖]019 Linux tcpdump 抓包案例入门可真简单啊?

    https://my.oschina.net/u/3113381/blog/5477908   1 tcpdump 是什么? tcpdump 可以将网络中传送的数据包完全截获下来提供分析.它支持针对网 ...