使用哈希表(Map)解决"只出现一次的数字 II"问题
目录
TOC
在 JavaScript 中, Map
是一种键值对存储结构,与普通对象不同,它的键可以是任意类型(对象、函数、基本类型等),并且会严格维护插入顺序。以下是对 map.set()
、 map.entries()
等核心方法的详细讲解:
map数据结构
1. map.set(key, value)
-
作用 :向
Map
中添加或更新一个键值对。 -
参数 :
-
key
: 键(可以是任意类型,如数字、字符串、对象等)。 -
value
: 值(任意类型)。 -
返回值 :
Map
对象本身(支持链式调用)。 -
示例 :
cobol
const map = new Map();
map.set("name", "Alice"); // 添加键值对 "name" => "Alice"
map.set(42, "Answer"); // 添加键值对 42 => "Answer"
map.set({ id: 1 }, true); // 对象作为键
// 更新已有键的值
map.set("name", "Bob"); // 修改 "name" 对应的值为 "Bob"
2. map.entries()
-
作用 :返回一个包含所有键值对的迭代器(Iterator),每个键值对以
[key, value]
数组形式表示。 -
返回值 :迭代器对象,可以通过
for...of
循环遍历,或转换为数组。
cobol
const map = new Map();
map.set("a", 1).set("b", 2);
// 使用 for...of 遍历
for (const [key, value] of map.entries()) {
console.log(key, value); // 输出 "a 1", "b 2"
}
// 转换为数组
const entriesArray = Array.from(map.entries());
console.log(entriesArray); // 输出 [["a", 1], ["b", 2]]
3. 其他常用 Map 方法
map.get(key)
获取键对应的值,若键不存在返回 undefined
。
cobol
map.get("a"); // 返回 1
map.get("c"); // 返回 undefined
map.has(key)
检查键是否存在,返回布尔值。
cobol
map.has("a"); // true
map.delete(key)
删除指定键的键值对,成功返回 true
,失败返回 false
。
cobol
map.delete("a"); // true
map.size
属性,返回 Map
中键值对的数量。
cobol
console.log(map.size); // 1(假设删除了 "a")
使用哈希表(Map)解决"只出现一次的数字 II"问题
题目描述
给定一个整数数组 nums
,其中恰好有一个元素仅出现一次,其余每个元素都恰好出现三次。要求找出那个只出现一次的元素。
解题思路
哈希表统计法
我们可以通过统计每个数字的出现次数来解决问题。由于目标元素只出现一次,其余元素出现三次,只需遍历数组记录频率,最后找到频率为1的元素即可。
哈希表(Map)的优势
-
快速查找与插入 :Map 允许以 O(1) 的平均时间复杂度进行键的查找和插入,适合快速统计频率。
-
清晰记录状态 :键值对结构直观记录每个数字的出现次数,便于后续遍历查找目标。
代码解析
cobol
var singleNumber = function (nums) {
let map = new Map();
// 第一次遍历:统计数字频率
for (let num of nums) {
if (map.has(num)) {
map.set(num, map.get(num) + 1);
} else {
map.set(num, 1);
}
}
// 第二次遍历:查找频率为1的键
for (let [key, value] of map.entries()) {
if (value === 1) {
return key;
}
}
};
步骤详解
-
初始化哈希表
创建一个
Map
对象map
,用于存储数字及其出现次数。 -
统计频率
遍历数组
nums
:
-
若当前数字
num
已存在于map
中,将对应值加1。 -
若不存在,则添加键值对
(num, 1)
。
- 查找目标元素
遍历map
的所有键值对,返回值为1的键,即只出现一次的元素。
示例演示
以输入 nums = [2, 2, 3, 2]
为例:
-
遍历结束后,
map
内容为{2 => 3, 3 => 1}
。 -
第二次遍历时,发现键
3
的值为1,返回结果3
。
复杂度分析
-
时间复杂度 :O(n)。两次独立遍历数组和哈希表,总体时间复杂度为线性。
-
空间复杂度 :O(n)。哈希表最多存储
n/3 + 1
个键值对,空间与输入规模成正比。
总结与拓展
本文使用哈希表法直观解决了问题,该方法具有通用性,可扩展至其他出现次数不同的场景(如找出出现两次的元素)。若追求空间效率优化,可采用位运算方法,但实现较为复杂。哈希表法在时间与代码可读性之间取得了良好平衡,是解决此类问题的经典思路。