两数之和

力扣题目链接(opens new window)

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

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

示例:

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

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

所以返回 [0, 1]

思路

暴力法

两层for循环,一个一个加起来然后判断呗

class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
for(int i = 0; i < nums.size(); i++){
for(int j = i + 1; j < nums.size(); j++){
if(nums[i] + nums[j] == target){
return {i, j};
}
}
}
//不满足条件返回空
return {};
}
};
哈希法

没错,这个题也可以用哈希法去解

只不过这里我们使用的哈希结构有所不同,先分析一下解题思路

题目要求我们找到数组中两个数,这两个数加起来要等于输入的target值

假设,现在遍历到数组的第一个数 A

C = target - A;

那么如果数组中存在 C 的话,我们就找到了两个符合条件的数{A, B},返回两者的下标即可

因此,我们需要有一个数据结构去存放已经遍历过的值和该值在数组中的下标

这是一个key-value的结构,对应到c++中可以通过map容器实现

C++中map,有三种类型:

映射 底层实现 是否有序 数值是否可以重复 能否更改数值 查询效率 增删效率
std::map 红黑树 key有序 key不可重复 key不可修改 O(log n) O(log n)
std::multimap 红黑树 key有序 key可重复 key不可修改 O(log n) O(log n)
std::unordered_map 哈希表 key无序 key不可重复 key不可修改 O(1) O(1)

std::unordered_map 底层实现为哈希表,std::map 和std::multimap 的底层实现是红黑树。

因为本题并不需要key有序,所以使用unordered_map效率更高

那么key对应什么?value又对应什么呢?

我们想知道的是,某个值(当前遍历值与target作差之后的差值)是否被遍历过,即查找的对象是某个值,因此需要将遍历得到的数组元素值作为key,其下标作为value

流程

1、遍历数组,向unordered_map中查询当前遍历值对应的值是否被遍历过

2、如果查询到匹配值,返回该值对应的value,与当前遍历值的index组成一对结果

代码

主要障碍是对c++里面一些容器的操作不熟练(比如这里的map容器),这里直接粘的卡哥的代码

class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
//声明一个unordered_map
std::unordered_map <int,int> map;
for(int i = 0; i < nums.size(); i++) {
// 遍历当前元素,并在map中寻找是否有匹配的key
// auto用于自动给迭代对象一个相应的数据类型
auto iter = map.find(target - nums[i]); //这里是定义了一个map的iterator吗?没见过这种写法
//end()指向的最后一个元素的后一个位置
//iter != map.end()是什么意思?其常被用于map容器遍历时的判断条件
//
if(iter != map.end()) { //找到了
/*
(*it).first会得到key,
(*it).second会得到value。
这等同于it->first和it->second
*/
//{匹配值下标, 当前遍历值的下标}
return {iter->second, i};
}
// 如果没找到匹配对,就把访问过的元素和下标加入到map中
map.insert(pair<int, int>(nums[i], i));
}
return {};
}
};

后续需要对c++容器的使用做强化训练(专题:c++刷题常用容器简介,TBD)

关于iter != map.end()

这里需要从它的上一行代码开始说起

摘自《C++ Primer Plus第6版》:

C++11新增了一个工具,让编译器能够根据初始值的类型推断变量的类型。为此,它重新定义了auto的含义。auto是一个C语言关键字,但很少使用,有关其以前的含义,请参阅第9章。在初始化声明中,如果使用关键字auto,而不指定变量的类型,编译器将把变量的类型设置成与初始值相同:

那么auto iter = map.find(target - nums[i]);的含义是:

定义一个 迭代器iter 用于在 map 中寻找 target - nums[i]

如果 map.find(target - nums[i]) 等于 map.end() ,那么键就没有找到

否则,find会返回一个指向找到的元素的迭代器

上述题解中的代码可写为:

std::unordered_map <int,int> map;
unordered_map <int,int> ::iterator it = map.find(target - nums[i]); if (i != m.end()) { /* 找到了, 此时i->first就是匹配值下标(key), i->second是当前遍历值的下标(value) */}
else { /* 没找到f */ }

参考:https://stackoverflow.com/a/1939962/15272780

二刷

简化了之前的代码

class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> hashmap;
for(int i = 0; i < nums.size(); ++i){
if(hashmap.find(target - nums[i]) != hashmap.end()){
return {hashmap[target - nums[i]], i};
}
hashmap.insert(pair<int, int>(nums[i], i));
}
return {};
}
};

有一个关键点是:我们是使用遍历值与target作差,差值作为key,下标作为value

所以可以通过差值查询“差值是否在map中”

【LeetCode哈希表#4】梦开始的地方:两数之和(map),以及关于容器map的一些代码技巧的更多相关文章

  1. LeetCode 170. Two Sum III - Data structure design (两数之和之三 - 数据结构设计)$

    Design and implement a TwoSum class. It should support the following operations: add and find. add - ...

  2. [LeetCode] 653. Two Sum IV - Input is a BST 两数之和之四 - 输入是二叉搜索树

    Given a Binary Search Tree and a target number, return true if there exist two elements in the BST s ...

  3. leetcode 刷题(数组篇)1题 两数之和(哈希表)

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

  4. 【leetcode】170. Two Sum III - Data structure design 两数之和之三 - 数据结构设计

    Design and implement a TwoSum class. It should support the following operations:  add and find. add  ...

  5. [LeetCode] 167. Two Sum II - Input array is sorted 两数和 II - 输入是有序的数组

    Given an array of integers that is already sorted in ascending order, find two numbers such that the ...

  6. [LeetCode] 170. Two Sum III - Data structure design 两数之和之三 - 数据结构设计

    Design and implement a TwoSum class. It should support the following operations:add and find. add - ...

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

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

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

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

  9. LeetCode:乘法表中的第K小的数【668】

    LeetCode:乘法表中的第K小的数[668] 题目描述 几乎每一个人都用 乘法表.但是你能在乘法表中快速找到第k小的数字吗? 给定高度m .宽度n 的一张 m * n的乘法表,以及正整数k,你需要 ...

  10. 167. 两数之和 II - 输入有序数组 + 哈希表 + 双指针

    167. 两数之和 II - 输入有序数组 LeetCode_167 题目描述 方法一:暴力法(使用哈希表) class Solution { public int[] twoSum(int[] nu ...

随机推荐

  1. Springboot下micrometer+prometheus+grafana进行JVM监控的操作过程

    Springboot下micrometer+prometheus+grafana进行JVM监控的操作过程 背景 同事今天提交了一个补丁. 给基于Springboot的产品增加了micrometer等收 ...

  2. [译]深入了解现代web浏览器(一)

    本文是根据Mariko Kosaka在谷歌开发者网站上的系列文章https://developer.chrome.com/blog/inside-browser-part1/ 翻译而来,共有四篇,该篇 ...

  3. Mybatis 拦截器实现单数据源内多数据库切换 | 京东物流技术团队

    物流的分拣业务在某些分拣场地只有一个数据源,因为数据量比较大,将所有数据存在一张表内查询速度慢,也为了做不同设备数据的分库管理,便在这个数据源内创建了多个不同库名但表完全相同的数据库,如下图所示: 现 ...

  4. 文盘Rust -- 如何把配置文件打包到二进制文件里

    ​在实际开发中,经常会遇到各种不同的配置文件.通常,程序运行的各种配置从外部读取,以增强应用配置的灵活性.java 生态中的 springboot 提供了这种设计的典范.springboot 的应用程 ...

  5. 基于密码学的身份混淆系统 -- idmix

    简介 Hyperledger Fabric的Idemix是一个基于密码学的身份混淆系统,它提供了一种在区块链网络中实现用户隐私的方法.Idemix的主要特性是它的零知识证明系统,这是一种允许用户证明他 ...

  6. 手撕Vue-数据驱动界面改变上

    经过上一篇的介绍,已经实现了监听数据的变化,接下来就是要实现数据变化后,界面也跟着变化,这就是数据驱动界面改变. 想要实现数据变化之后更新UI界面,我们可以使用发布订阅模式来实现,先定义一个观察者类, ...

  7. Keepalive-Haproxy高可用介绍

    假设我们现在开发了一个应用应用的端口号为 8080,这个应用我们想让它去实现一个负载均衡的访问,就是说我们有两台服务器都部署了我们的 8080 应用,我们想让它一会访问 ip 为: 192.168.0 ...

  8. Python库【数据处理、机器学习、大数据、文件处理等14个类的所有python库整理】

    吐血整理一个月--终于把所有Python库整理齐了....._小熊猫爱恰饭的博客-CSDN博客 参考链接: 一.数据处理 #python学习资料群:660193417 ##3 Chardet # 字符 ...

  9. 【七】强化学习、gym学习平台扩充,更好的玩转虚拟环境,关于mujoco、mujoco-py、baselines安装配置

    相关文章: [一]gym环境安装以及安装遇到的错误解决 [二]gym初次入门一学就会-简明教程 [三]gym简单画图 [四]gym搭建自己的环境,全网最详细版本,3分钟你就学会了! [五]gym搭建自 ...

  10. Python 多线程爬取西刺代理

    西刺代理是一个国内IP代理,由于代理倒闭了,所以我就把原来的代码放出来供大家学习吧. 首先找到所有的tr标签,与class="odd"的标签,然后提取出来. 然后再依次找到tr标签 ...