壹 ❀ 引

在学习算法基础的同时,我还是继续捡起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. 配置Maven项目时无法找到依赖

    1.问题 在配置pom.xml文件时,关于plugin插件配置时,遭遇许多类似 未找到插件 'maven-clean-plugin:3.1.0' 未找到插件 'org.apache.maven.plu ...

  2. vscode - Prettier插件 统一代码风格规范,保存自动格式化代码

    安装 Prettier - Code formatter prettier安装完毕,使用shift+alt+f就可格式化代码. 如果需要自动保存,要在系统设置中增加"editor.forma ...

  3. 代码使我头疼之React初学习

    前言 开始了,去年(2020)说要学的React,到现在2021年的12月底了,才来实施--(年底警告!年末总结还没开始写!) 不过前端为啥要学React呢?Vue不是很好用吗?Vue确实很好用,并且 ...

  4. [转帖]nginx 剖析 request_time和upstream_response_time的误区、区别

    https://cloud.tencent.com/developer/article/1767981 首先,澄清一个误区 upstream_response_time必须在upstream配置时才能 ...

  5. [转帖]sql_exporter的使用

    https://www.jianshu.com/p/df4b7a7cfc0d 一.背景 有些时候,我们想看每天系统的登录人数.或者系统中订单的数据,比如:成功的订单.异常的订单等等.这些数据都在我们的 ...

  6. [转帖]Unix Domain Socket– IPC通信机制

    什么是Unix Domain Socket 基于socket的框架上发展出一种IPC机制,就是UNIX Domain Socket.虽然网络socket也可用于同一台主机的进程间通讯(通过loopba ...

  7. [转帖]br 备份时排除某个库

    https://tidb.net/book/tidb-monthly/2023/2023-02/usercase/excluded-a-storeroom-during-br-backup 生产环境中 ...

  8. [转帖]《Linux性能优化实战》笔记(23)—— 内核线程 CPU 利用率过高,perf 与 火焰图

    在排查网络问题时,我们还经常碰到的一个问题,就是内核线程的 CPU 使用率很高.比如,在高并发的场景中,内核线程 ksoftirqd 的 CPU 使用率通常就会比较高.回顾一下前面学过的 CPU 和网 ...

  9. CentOS7 和 CentOS8 安装 rusers-server 然后使用LR 实时监控Linux主机性能的办法

    LR 能够通过RPC 的工具 实时获取 被压测机器的 性能表现 但是需要安装几个组件. CentOS6 时期比较简单 可以通过网上 下载rstatd 的tar 包离线安装即可 但是发现CentOS7 ...

  10. 在WPF应用中实现DataGrid的分组显示,以及嵌套明细展示效果

    我在前面随笔<在Winform系统开发中,对表格列表中的内容进行分组展示>,介绍了Winform程序中对表格内容进行了分组的展示,在WPF应用中,同样也可以对表格的内容进行分组展示,不过处 ...