1. 两数之和

1. 两数之和

暴力法

思路
两层for循环,外层for循环i遍历数组元素,内层for循环j遍历[i+1, n-1]范围内剩余元素,若nums[i]+nums[j] = target,返回[i,j]。

哈希表(map)

思路
一层for循环i遍历数组元素,判断当前元素nums[i]的另一半(target - nums[i])是否在哈希表map中。
若在,返回这两个元素下标;
若不在,将当前元素nums[i]及下标i加入map中。

本质是用哈希表(map)优化了暴力法中的第二层for循环,本解法使用 unordered map数据结构,从map中查找元素时间复杂度为O(1),相当于用空间换取时间,将暴力法第二层for循环时间复杂度降到O(1)。

进阶

  • 为什么想到用哈希表?
    哈希表适用场景:(1)判断一个元素是否在集合中。(2)判断一个元素是否在集合中出现过。
    暴力法第二层for循环目的是从子数组中查找一个元素

  • 为什么用哈希表(map)?
    可用三种数据结构实现哈希表:数组、set、map。
    数组:数组长度固定,初始化后不能更改。数组长度必须大于元素最大数量。
    set:元素不重复,可增删元素。
    map:存储(key, value)键值对,key不重复。
    本题nums元素最多为10^4,若采用数组实现哈希表,浪费存储空间。若使用set,则无法同时存储数组元素及下标。使用map实现哈希表,key存储数组元素,value存储下标。

  • map中存储什么?
    map中存储(key, value)对,key不重复。

  • map的key存储什么?value存储什么?
    key存储数组元素,value存储下标。

class Solution {
    public int[] twoSum(int[] nums, int target) {
        // 哈希表(unordered map),key 存储数组元素,value 存储下标
        Map<Integer, Integer> map = new HashMap<>();
        int[] res = new int[2]; // 存储和为 target 的元素下标

        for (int i = 0; i < nums.length; i++) {
            // 判断 nums[i] 的另一半(target - nums[i])是否在 map 中
            int key = target - nums[i];
            if (map.containsKey(key)) { // 在 map 中查找是否有与 nums[i] 匹配的 key
                res[1] = i;
                res[0] = map.get(key);
                break;
            } else {
                map.put(nums[i], i); // 不匹配,把当前访问的元素及下标加入 map 中
            }
        }

        return res;
    }
}
posted @ 2025-10-18 20:43  Nickey103  阅读(4)  评论(0)    收藏  举报