【哈希表】leetcode1. 两数之和(C/C++/Java/Python/Js)

news2024/12/25 22:36:51

leetcode1. 两数之和

  • 1 题目
  • 2 思路
  • 3 代码
    • 3.1 C++版本
    • 3.2 C版本
    • 3.3 Java版本
    • 3.4 Python版本
    • 3.5 JavaScript版本
  • 4 总结


1 题目

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

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:

输入:nums = [3,3], target = 6
输出:[0,1]

提示:

2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
只会存在一个有效答案


2 思路

很明显暴力的解法是两层for循环查找,时间复杂度是O(n^2)。

建议大家做这道题目之前,先做一下这两道
【哈希表】leetcode349. 两个数组的交集(C/C++/Java/Python/Js)
【哈希表】leetcode242.有效的字母异位词(C/C++/Java/Python/Js)

leetcode242.有效的字母异位词 这道题目是用数组作为哈希表来解决哈希问题,349. 两个数组的交集这道题目是通过set作为哈希表来解决哈希问题或者利用快慢指针。

什么时候使用哈希法
当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。

对于本题:
需要一个集合来存放我们遍历过的元素,然后在遍历数组的时候去询问这个集合,某元素是否遍历过,也就是 是否出现在这个集合。

那么我们就应该想到使用哈希法了。

因为本地,我们不仅要知道元素有没有遍历过,还有知道这个元素对应的下标,需要使用 key value结构来存放,key来存元素,value来存下标,那么使用map正合适。

使用数组和set来做哈希法的局限:

  • 数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。
  • set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下标位置,因为要返回x 和 y的下标。所以set 也不能用。

此时就要选择另一种数据结构:map ,map是一种key value的存储结构,可以用key保存数值,用value在保存数值所在的下标。

C++中map,有三种类型:
在这里插入图片描述
std::unordered_map 底层实现为哈希表,std::map 和std::multimap 的底层实现是红黑树。

同理,std::map 和std::multimap 的key也是有序的(这个问题也经常作为面试题,考察对语言容器底层的理解)。 更多哈希表的理论知识请看关于哈希表,你该了解这些! 。

这道题目中并不需要key有序,选择std::unordered_map 效率更高!

map目的用来存放我们访问过的元素,因为遍历数组的时候,需要记录我们之前遍历过哪些元素和对应的下表,这样才能找到与当前元素相匹配的(也就是相加等于target)

接下来是map中key和value分别表示什么:
这道题 我们需要 给出一个元素,判断这个元素是否出现过,如果出现过,返回这个元素的下标。

那么判断元素是否出现,这个元素就要作为key,所以数组中的元素作为key,有key对应的就是value,value用来存下标。

所以 map中的存储结构为 {key:数据元素,value:数组元素对应的下表}。

在遍历数组的时候,只需要向map去查询是否有和目前遍历元素比配的数值,如果有,就找到的匹配对,如果没有,就把目前遍历的元素放进map中,因为map存放的就是我们访问过的元素。

过程如下:
在这里插入图片描述
在这里插入图片描述


3 代码


3.1 C++版本

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        std::unordered_map <int,int> map;
        for(int i = 0; i < nums.size(); i++) {
            // 遍历当前元素,并在map中寻找是否有匹配的key
            auto iter = map.find(target - nums[i]); 
            if(iter != map.end()) {
                return {iter->second, i};
            }
            // 如果没找到匹配对,就把访问过的元素和下标加入到map中
            map.insert(pair<int, int>(nums[i], i)); 
        }
        return {};
    }
};


3.2 C版本


struct hashTable {
    int key;
    int val;
    UT_hash_handle hh;
};

struct hashTable* hashtable;

struct hashTable* find(int ikey) {
    struct hashTable* tmp;
    HASH_FIND_INT(hashtable, &ikey, tmp);
    return tmp;
}

void insert(int ikey, int ival) {
    struct hashTable* it = find(ikey);
    if (it == NULL) {
        struct hashTable* tmp = malloc(sizeof(struct hashTable));
        tmp->key = ikey, tmp->val = ival;
        HASH_ADD_INT(hashtable, key, tmp);
    } else {
        it->val = ival;
    }
}

int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
    hashtable = NULL;
    for (int i = 0; i < numsSize; i++) {
        struct hashTable* it = find(target - nums[i]);
        if (it != NULL) {
            int* ret = malloc(sizeof(int) * 2);
            ret[0] = it->val, ret[1] = i;
            *returnSize = 2;
            return ret;
        }
        insert(nums[i], i);
    }
    *returnSize = 0;
    return NULL;
}

3.3 Java版本


public int[] twoSum(int[] nums, int target) {
    int[] res = new int[2];
    if(nums == null || nums.length == 0){
        return res;
    }
    Map<Integer, Integer> map = new HashMap<>();
    for(int i = 0; i < nums.length; i++){
        int temp = target - nums[i];   // 遍历当前元素,并在map中寻找是否有匹配的key
        if(map.containsKey(temp)){
            res[1] = i;
            res[0] = map.get(temp);
            break;
        }
        map.put(nums[i], i);    // 如果没找到匹配对,就把访问过的元素和下标加入到map中
    }
    return res;
}

3.4 Python版本


class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        records = dict()

        for index, value in enumerate(nums):  
            if target - value in records:   # 遍历当前元素,并在map中寻找是否有匹配的key
                return [records[target- value], index]
            records[value] = index    # 遍历当前元素,并在map中寻找是否有匹配的key
        return []

3.5 JavaScript版本


var twoSum = function (nums, target) {
  let hash = {};
  for (let i = 0; i < nums.length; i++) {  // 遍历当前元素,并在map中寻找是否有匹配的key
    if (hash[target - nums[i]] !== undefined) {
      return [i, hash[target - nums[i]]];
    }
    hash[nums[i]] = i;   // 如果没找到匹配对,就把访问过的元素和下标加入到map中
  }
  return [];
};

4 总结

本题其实有四个重点:

  • 为什么会想到用哈希表
  • 哈希表为什么用map
  • 本题map是用来存什么的
  • map中的key和value用来存什么的

Carl哥的视频讲解

By – Suki 2023/1/31

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/189151.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

iPad 屏幕镜像到 macbook

将iPad 到屏幕投屏到 macbook&#xff0c;只需要三步就可以实现用数据线连接ipad和macbook在macbook的应用中找到QuickTime Player&#xff0c;打开QuickTime Player&#xff0c;在【文件】中选择【新建影片】在弹出窗口的小箭头中&#xff0c;选择需要的iPad名称通过数据线连接…

目标跟踪心得篇七:解决目标跟踪评价指标输出为0或异常(Trackeval、MMtracking)

如果在做跟踪任务测评时,发现输出的评价指标全为0或者异常值时该怎么办(如下图)?博主调试了很久发现其实这是MMtracking的一个Bug,因此如果不是用MMtracking框架的话本节可能对你帮助不大。 大致有以下两个内容: TrackEval目前还不能做到对多类别的MOT任务计算评价指标,…

FDD与TDD

TDD&#xff0c;时分双工(Time Division Duplexing) FDD&#xff0c;频分双工(Frequency Division Duplexing) 帮助理解&#xff1a; 1.FDD&#xff1a;双车道&#xff0c;一个车道只能走一个方向&#xff0c;双向互不干扰。 2.TDD&#xff1a;单车道&#xff0c;不同时间允…

RabbitMQ看这一篇文章就够了

第一章 RabbitMQ介绍 第1节 MQ是什么 1 2 3 41. 消息队列(Message Queue),又叫做消息中间件 2. 用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成 3. 通过提供消息传递和消息队列模型,可以在分布式环境下扩展进程的通信 4. MQ 是用来解…

北斗短报文遥测终端机在水雨情监测系统中的应用

一、方案概述 我国水利监管手段比较单一&#xff0c;水雨情监测移动公网覆盖不足等诸多问题&#xff0c;利用北斗短报文通信技术数字化信息采集技术&#xff0c;实现水文自动测报&#xff0c;大幅度提升湿地生态和水域的监测、查询、预警和应急处理能力。在恶劣天气情况或特殊灾…

360(drizzleDumper)脱壳教程“某药数据”

一、drizzleDumper的下载使用 1.上GitHub下载开源的脱壳工具mirrors / DrizzleRisk / drizzleDumper GitCodedrizzleDumper是一款基于内存搜索的Android脱壳工具。 &#x1f680; Github 镜像仓库 &#x1f680; 源项目地址 ⬇ ⬇...https://gitcode.net/mirrors/DrizzleRisk…

ZedGraph如何显示鼠标附近的曲线的点?介绍三种方法

使用ZedGraph绘制曲线图的时候&#xff0c;不仅仅是看曲线的走向&#xff0c;也需要查看曲线上某位位置处采集到的数据是多少。下面介绍三种方法&#xff0c;从简单到复杂。 文章目录1、使用自带的功能显示点的坐标2、 多条曲线的坐标点同时显示3、 多条曲线的坐标点同时显示&a…

100%国产C2000,P2P替代TMS320F280049C,独立32位双核CPU,主频高达400MHz

一、特性参数 1、独立双核&#xff0c;32位CPU&#xff0c;单核主频400MHz 2、IEEE 754 单精度浮点单元 &#xff08;FPU&#xff09; 3、三角函数单元 &#xff08;TMU&#xff09; 4、1MB 的 FLASH &#xff08;ECC保护&#xff09; 5、1MB 的 SRAM &#xff08;ECC保护&…

docker基础简介

一、docker架构 二、Docker 基本命令 1、查看 Docker 版本 查看 Docker 版本包括 Docker 版本号、API 版本号、对应的 Git Commit、Containerd 和 runC的版本信息等。 # docker version Client: Docker Engine - Community Version: 20.10.4 API version: 1.40 Go version: …

新手小白做跨境电商应该从哪里入手?

想从事跨境电商先从哪里入手?米贸搜整理如下&#xff0c;希望可以帮助到你跨境电商平台&#xff0c;如&#xff1a;Amazon、eBay、aliexpress、Cdiscount、wish等。想从事跨境电商&#xff0c;你得搭建电商团队&#xff0c;先从跨境电商平台的入驻入手&#xff0c;弄清楚入驻条…

【设计模式】行为型模式·模板方法模式

学习汇总入口【23种设计模式】学习汇总(数万字讲解体系思维导图) 一.概述 定义一个操作中的算法骨架&#xff0c;而将算法的一些步骤延迟到子类中&#xff0c;使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。 在面向对象程序设计过程中&#xff0c;程序员常…

HTB_Inclued_TFTP文件包含与LXD提权

文章目录信息收集TFTPLXD 提权环境安装报错信息收集 开放80端口&#xff0c;url为http://ip:port?filehome.php 测试文件包含&#xff0c;本地包含成功&#xff0c;远程失败&#xff0c;尝试上传后门木马反弹shell 根据图示&#xff0c;网站目录为var/www&#xff0c;其他功…

minio 使用docker安装和入门案例demo

minio目录1.安装2.页面web访问3.在界面上传4.使用api上传5.使用api下载目录 公司目前用到文件上传&#xff0c;考虑到费用等情况&#xff0c;可以在公司自己的服务器上搭建一下。本人记录minio的使用情况。 “前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&…

搭建 SpringBoot 项目

创建 SpringBoot 项目 配置application.properties 根据自己数据库进行配置 spring.datasource.nameexamspring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver spring.datasource.usernameroot spring.datasource.passwordroot spring.datasource.urljdbc:mysql://1…

振弦采集模块VMTool配置工具 快速测试功能

振弦采集模块VMTool配置工具 快速测试功能 本章演示在计算机上通过 VMTool 工具读取振弦传感器数据。 假设您的计算机已经有至少一个空闲的 COM 接口。 1 检查 COM 接口名称 在操作系统桌面右键点击“ 我的电脑” &#xff0c; 选择【 属性】&#xff0c;弹出计算机属性对话框&…

X-Bogus流程分析

声明&#xff1a;本文仅限学习交流使用&#xff0c;禁止用于非法用途、商业活动等。否则后果自负。如有侵权&#xff0c;请告知删除&#xff0c;谢谢&#xff01;本教程也没有专门针对某个网站而编写&#xff0c;单纯的技术研究 目录 一、混淆还原 二、插桩还原 三、还原X-B…

关于Vue中Diff算法详解

一、(Diff)是什么? diff 算法是一种通过同层的树节点进行比较的高效算法 1.1. 特点&#xff1a; 比较只会在同层级进行, 不会跨层级比较在diff比较的过程中&#xff0c;循环从两边向中间比较diff 算法的在很多场景下都有应用&#xff0c;在 vue 中&#xff0c;作用于虚拟 dom…

DAMA数据管理知识体系指南之数据治理

第3章 数据治理 3.1 简介 数据治理是对数据资产管理行使权力和控制的活动集合(规划、监控和执行&#xff09;。数据治理职能指导其他数据管理职能如何执行。数据治理是在高层次上执行数据管理制度。 3.2 概念和活动 有效的数据管理&#xff0c;特别是在数据治理方面&#…

2023最新前端面试题4(持续更新)

JavaScript 59、JS的几条基本规范 1、不要在同一行声明多个变量 2、请使用/&#xff01;来比较true/false或者数值 3、使用对象字面量替代new Array这种形式 4、不要使用全局变量 5、Switch语句必须带有default分支 6、函数不应该有时候有返回值&#xff0c;有时候没有返回值 …

如何写出有效的单元测试?

如何写出有效的单元测试&#xff1f; 目录&#xff1a;导读 什么是单元测试 为什么需要单元测试 什么是有效的单元测试 为什么有效的单元测试如此重要 如何写有效的单元测试 补充单元测试应该从哪里开始 可测试的设计 单元测试与重构 做不到TDD&#xff0c;可以做到测…