跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava算法

两数之和:哈希表解法

针对 LeetCode 两数之和问题,提供双重遍历与哈希表两种解法。双重遍历暴力枚举所有组合,时间复杂度 O(n²)。哈希表法利用空间换时间,遍历数组时将元素及其下标存入哈希表,通过计算补数 target - nums[i] 快速查找是否存在匹配项,将时间复杂度优化至 O(n)。Java 代码示例演示了 HashMap 的初始化、键值对存储及查找操作,确保在不使用相同元素的前提下返回正确下标。

月亮邮递员发布于 2026/3/16更新于 2026/7/2145 浏览
两数之和:哈希表解法

两数之和

给定一个整数数组 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 <= 10^4 -10^9 <= nums[i] <= 10^9 -10^9 <= target <= 10^9

只会存在一个有效答案

进阶:你可以想出一个时间复杂度小于 O(n²) 的算法吗?

解法一(双重遍历)

依题意需在数组中找到两个元素使得 a + b = target,由于题目要求

你不能使用两次相同的元素

不难想到使用双重遍历逐一验证,即找出数组中所有两两不同的数组元素的排列组合,并逐一验证二者之和是否为 target。当然我们也可以用 target - a 得到 b,验证 a 之后的元素中是否含有 b。

1. 验证二者之和是否为 target

class Solution {
    public int[] twoSum(int[] nums, int target) {
        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[i] + nums[j] == target) {
                    return new int[]{i, j};
                }
            }
        }
        return new int[0];
    }
}

2. 验证 target - nums[i] 是否存在于后续元素中

class Solution {
    public int[] twoSum(int[] nums, int target) {
         (   ; i < nums.length; i++) {
               target - nums[i];
             (   i + ; j < nums.length; j++) {
                 (nums[j] == complement) {
                      []{i, j};
                }
            }
        }
          [];
    }
}
for
int
i
=
0
int
complement
=
for
int
j
=
1
if
return
new
int
return
new
int
0

然而 n 个元素两两组合共有 n(n-1)/2 种组合,逐一验证会使时间复杂度达到 O(n²)。

图片描述

虽然已经完成了题目的要求,但是仍有十分大的优化空间。

解法二(哈希表)

解法一中的大部分时间都用在了验证是否存在 b 元素上,那么我们有没有什么方法来缩短这一流程呢?有的,这个方法就是——'哈希表'。

class Solution {
    public int[] twoSum(int[] nums, int target) {
        // 使用哈希表可将时间复杂度优化至 O(1)
        // 使用 new 动态分配存储空间,注意 <> 不能忘记
        // 若开头使用 import java.util.HashMap 则此处可直接使用 HashMap
        // 第一个 Integer 为数组元素(key),第二个 Integer 为数组下标(value)
        java.util.HashMap<Integer, Integer> map = new java.util.HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int complement = target - nums[i];
            // map.containsKey() 用于判断键是否存在于哈希表中,返回值为 bool 类型
            if (map.containsKey(complement)) {
                // map.get() 用于查找 Key = complement 对应的 value
                return new int[]{map.get(complement), i};
            }
            // map.put(a,b) 表示存入键值对 a-b,其中 a 为键,b 为值
            map.put(nums[i], i);
        }
        return new int[0];
    }
}
1. 有关哈希表

原理

哈希表(Hash Table)是一种通过键(Key)直接访问值(Value)的数据结构,其核心思想是利用哈希函数将键映射到存储位置(称为哈希桶或槽位)。这种映射使得查找、插入和删除操作的平均时间复杂度接近 O(1)。

当我们在哈希表中存储元素(value)时,我们需要为其绑定一个键(key),系统会使用哈希函数计算该元素的存储位置。例如,对字符串键 "apple" 的简单哈希函数可能是字符 ASCII 码之和取模表大小: hash("apple") = (97 + 112 + 112 + 108 + 101) % table_size 于是系统便会按照计算得到的值为元素分配存储空间,并将 key-value 作为一个整体(entry)存入表中。当我们下次查找该元素时,系统会再次计算该元素的键(key)哈希值,并根据该值去计算元素的存储位置。使用哈希表可将单次查找 / 插入操作的平均时间复杂度优化至 O(1),整体算法的时间复杂度优化至 O(n)。

图片描述

2. 关于本题的解题思路

首先先来介绍下代码中使用到的语法及作用。

初始化

// 先 import 后使用
import java.util.HashMap;
HashMap<Integer, Integer> map = new HashMap<>();
// 使用全限定域名
java.util.HashMap<Integer, Integer> map = new java.util.HashMap<>();

(需注意,哈希表中的类型声明首字母应大写,如:Integer、Double、String、Boolean)

判断键是否存在

map.containsKey(key)

存储键值对

map.put(key, value)

根据键获取值

map.get(key)

本题的操作对象为数组,简直完美符合哈希表的应用场景(数组下标和数组元素完美组成键值对)。由于解法二的思路是在哈希表中查找补数 complement 并返回其数组下标,于是我们顺理成章将数组元素作为 key,将数组下标作为 value。

首先对数组进行遍历:

for (int i = 0; i < nums.length; i++)

计算补数 complement:

int complement = target - nums[i]

接下来开始判断 complement 是否存在于哈希表中。若存在则直接返回 complement (即为哈希表中的 key) 在哈希表中的 value(即为 complement 的数组下标)和当前元素的数组下标:

if (map.containsKey(complement)) {
    return new int[]{map.get(complement), i};
}

但哈希表初始为空,那怎么能根据 key 查得到对应的 value 呢?

这个问题很好解决,我们可以在查找 complement 失败后将当前数组元素和数组下标作为键值对存储进哈希表:

map.put(nums[i], i);

因为题目要求是

请你在该数组中找出和为目标值 target 的那两个整数,并返回它们的数组下标

所以 complement 的范围已经确定,当将数组遍历完成后,所有的数组元素(即所有可能存在的 complement)也都存储到了哈希表中。

那对第一个元素的 complement 进行查询的时候,哈希表为空,会不会导致数组元素中原本有他的 complement,但由于后面元素还没有存储进哈希表,导致漏解呢?

我们应该这么想,补数是相互的,比如 2 + 7 = 9,那么 2 的补数就是 7,同样 7 的补数就是 2。假设数组长度为 5,2 为第一个数组元素,7 为第四个数组元素,在哈希表中对 2 进行补数查找时,哈希表为空,查找失败,于是将数组元素 2 及其数组下标作为键值对存储进哈希表,等到数组元素遍历到 7 时,其补数为 2,而 2 已经在哈希表中,补数查找成功。

由此可见并不会出现漏解的情况。

目录

  1. 两数之和
  2. 解法一(双重遍历)
  3. 解法二(哈希表)
  4. 1. 有关哈希表
  5. 2. 关于本题的解题思路
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • OpenClaw Skills 安装与实战:构建 AI 技能工具箱
  • 中国 AI 大模型未来五年五大潜力应用场景展望
  • K-means 聚类算法原理与实现详解
  • 基于YOLOv10n-SOEP-PST的助老机器人目标检测系统详解
  • 2026-03-18 AI 论文盘点:6 篇新作看记忆、长上下文与机器人策略
  • Linux 文件系统核心:磁盘 CHS/LBA 寻址与 inode 基础
  • 大模型在医疗领域的九大应用场景
  • Ubuntu 下 MySQL 数据库基础操作与字符集配置
  • C++ 类和对象进阶:四大默认成员函数与 const 对象详解
  • Python、NumPy、Pandas 与 Matplotlib 版本兼容指南
  • Rust 集合类型与迭代器详解
  • 前端调试:如何使用 debugger 设置断点
  • 基于SpringBoot和Vue的制造装备物联及生产管理系统
  • gpt-oss-20b-WEBUI 本地部署与使用指南
  • 基于 OpenAI Python SDK 的 API 调用示例脚本
  • 多模态基础大模型技术白皮书解读与核心挑战分析
  • LangBot:企业级即时通讯 AI 机器人平台介绍
  • 宇树机器人 G1 导航仿真:地图转换与参数配置
  • 大模型面试核心知识点与参考答案
  • JavaScript WebAPI 实战指南:DOM 操作与事件处理

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online