LeetCode Hot100(1/100)——1. 两数之和 (Two Sum)

文章目录

      • 题目描述
      • 解法一:暴力枚举法 (Brute Force)
        • [1. 思路解析](#1. 思路解析)
        • [2. 流程图 (Mermaid)](#2. 流程图 (Mermaid))
        • [3. Java 代码实现](#3. Java 代码实现)
        • [4. 复杂度分析](#4. 复杂度分析)
      • [解法二:哈希表法 (Hash Map) ------ **推荐解法**](#解法二:哈希表法 (Hash Map) —— 推荐解法)
        • [1. 思路解析](#1. 思路解析)
        • [2. 状态演变图解](#2. 状态演变图解)
        • [3. 逻辑流程图 (Mermaid)](#3. 逻辑流程图 (Mermaid))
        • [4. Java 代码实现](#4. Java 代码实现)
        • [5. 复杂度分析](#5. 复杂度分析)
      • 总结对比

题目描述

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

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

示例:

输入:nums = [2,7,11,15], target = 9

输出:[0,1]

解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1]


解法一:暴力枚举法 (Brute Force)

1. 思路解析

这是最直观的思路。我们需要找到两个数,不妨设为 xy

我们可以通过两层循环来遍历数组:

  • 第一层循环 选取第一个数 x (索引为 i)。
  • 第二层循环 选取第二个数 y (索引为 j)。
  • 判断 nums[i] + nums[j] 是否等于 target
  • 注意:题目要求不能使用同一个元素,所以内层循环从 i + 1 开始。
2. 流程图 (Mermaid)







开始
外层循环 i 从 0 到 n-1
i < n ?
内层循环 j 从 i+1 到 n-1
j < n ?
nums[i] + nums[j] == target ?
找到答案! 返回 {i, j}
j++
i++
未找到答案 (理论上不会到达)

3. Java 代码实现
java 复制代码
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int n = nums.length;
        // 第一层循环
        for (int i = 0; i < n; i++) {
            // 第二层循环,从 i+1 开始,避免重复和自身相加
            for (int j = i + 1; j < n; j++) {
                // 判断和是否为 target
                if (nums[i] + nums[j] == target) {
                    return new int[]{i, j};
                }
            }
        }
        return new int[0]; // 题目保证有解,此处仅为语法完整
    }
}
4. 复杂度分析
  • 时间复杂度 : O ( N 2 ) O(N^2) O(N2)。最坏情况下,我们需要遍历几乎所有的元素对。对于较大的数组,这种方法会非常慢。
  • 空间复杂度 : O ( 1 ) O(1) O(1)。只使用了常数个变量存储索引。

解法二:哈希表法 (Hash Map) ------ 推荐解法

1. 思路解析

暴力法的瓶颈在于:对于每个 x,我们需要遍历数组来寻找是否存在 target - x。这个查找过程是 O ( N ) O(N) O(N) 的。

我们可以利用 哈希表 (HashMap) 这种数据结构,利用其 O ( 1 ) O(1) O(1) 的查找时间复杂度来优化算法。

  • 我们在遍历数组的过程中,将元素的值和它的索引存入哈希表。
  • 核心逻辑 :在遍历当前元素 num 时,先检查哈希表中是否存在 target - num(即补数)。
    • 如果存在,说明之前已经遍历过那个数了,直接返回两个索引。
    • 如果不存在,将当前元素 num 和它的索引 i 存入哈希表,供后面的元素查找。
2. 状态演变图解

假设 nums = [2, 7, 11, 15], target = 9

步骤 当前索引 (i) 当前数值 (num) 需要寻找的补数 (target - num) 哈希表状态 (Check -> Put) 结果
1 0 2 9 - 2 = 7 Map中含7吗? No 。 Put {2: 0} 继续
2 1 7 9 - 7 = 2 Map中含2吗? Yes (index 0)。 找到! 返回 [0, 1]
3. 逻辑流程图 (Mermaid)



开始
初始化 HashMap
遍历数组 nums
获取当前元素 nums/i
计算补数: complement = target - nums/i
Map中包含 key 为

complement 吗?
获取 Map.get/complement

作为第一个索引
返回 {mapIndex, i}
结束
将 {nums/i : i}

存入 Map

4. Java 代码实现
java 复制代码
import java.util.HashMap;
import java.util.Map;

class Solution {
    public int[] twoSum(int[] nums, int target) {
        // 创建哈希表,Key存放数值,Value存放索引
        Map<Integer, Integer> map = new HashMap<>();
        
        for (int i = 0; i < nums.length; i++) {
            int complement = target - nums[i];
            
            // 检查哈希表中是否存在我们需要的那个"补数"
            if (map.containsKey(complement)) {
                // 如果存在,直接返回 [补数的索引, 当前索引]
                return new int[] { map.get(complement), i };
            }
            
            // 如果不存在,将当前数字和索引存入哈希表
            map.put(nums[i], i);
        }
        
        return new int[0];
    }
}
5. 复杂度分析
  • 时间复杂度 : O ( N ) O(N) O(N)。我们只遍历了包含 N N N 个元素的数组一次。在表中进行每次查找花费 O ( 1 ) O(1) O(1) 的时间。
  • 空间复杂度 : O ( N ) O(N) O(N)。最坏情况下,我们需要将 N N N 个元素都存入哈希表中(例如数组中没有匹配对,或者匹配对在最后两个)。

总结对比

特性 暴力枚举法 哈希表法 (最优)
核心思想 双重循环遍历 空间换时间 (查表)
时间复杂度 O ( N 2 ) O(N^2) O(N2) (慢) O ( N ) O(N) O(N) (快)
空间复杂度 O ( 1 ) O(1) O(1) (省空间) O ( N ) O(N) O(N) (耗空间)
代码简洁度 简单 适中
适用场景 N 非常小的时候 通用场景,尤其是大数据量
相关推荐
进击的小头2 小时前
常用数字滤波器的特性与适用场景
c语言·算法
狐572 小时前
2026-01-19-LeetCode刷题笔记-1292-元素和小于等于阈值的正方形的最大边长
笔记·算法·leetcode
张祥6422889043 小时前
误差理论与测量平差基础笔记六
笔记·算法·概率论
mjhcsp3 小时前
透彻背包DP:从DFS暴力搜索到动态规划的逐步推导
算法·深度优先·动态规划
学嵌入式的小杨同学3 小时前
【嵌入式 C 语言实战】交互式栈管理系统:从功能实现到用户交互全解析
c语言·开发语言·arm开发·数据结构·c++·算法·链表
多米Domi0113 小时前
0x3f 第40天 setnx的分布式锁和redission,写了一天项目书,光背了会儿八股,回溯(单词搜索)
数据结构·算法·leetcode
乐迪信息3 小时前
乐迪信息解决港口船型识别难题!AI算法盒子检测船舶类型
人工智能·算法·智能电视
梭七y4 小时前
【力扣hot100题】(151)课程表
算法·leetcode·哈希算法
孞㐑¥4 小时前
算法—滑动窗口
开发语言·c++·经验分享·笔记·算法