使用哈希表(Map)解决“只出现一次的数字 II”问题

使用哈希表(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;
    }
  }
};
步骤详解
  1. 初始化哈希表

    创建一个 Map 对象 map ,用于存储数字及其出现次数。

  2. 统计频率

    遍历数组 nums

  • 若当前数字 num 已存在于 map 中,将对应值加1。

  • 若不存在,则添加键值对 (num, 1)

  1. 查找目标元素
    遍历 map 的所有键值对,返回值为1的键,即只出现一次的元素。
示例演示

以输入 nums = [2, 2, 3, 2] 为例:

  • 遍历结束后, map 内容为 {2 => 3, 3 => 1}

  • 第二次遍历时,发现键 3 的值为1,返回结果 3

复杂度分析

  • 时间复杂度 :O(n)。两次独立遍历数组和哈希表,总体时间复杂度为线性。

  • 空间复杂度 :O(n)。哈希表最多存储 n/3 + 1 个键值对,空间与输入规模成正比。

总结与拓展

本文使用哈希表法直观解决了问题,该方法具有通用性,可扩展至其他出现次数不同的场景(如找出出现两次的元素)。若追求空间效率优化,可采用位运算方法,但实现较为复杂。哈希表法在时间与代码可读性之间取得了良好平衡,是解决此类问题的经典思路。

相关推荐
人工智能训练4 小时前
【极速部署】Ubuntu24.04+CUDA13.0 玩转 VLLM 0.15.0:预编译 Wheel 包 GPU 版安装全攻略
运维·前端·人工智能·python·ai编程·cuda·vllm
会跑的葫芦怪5 小时前
若依Vue 项目多子路径配置
前端·javascript·vue.js
xiaoqi9226 小时前
React Native鸿蒙跨平台如何进行狗狗领养中心,实现基于唯一标识的事件透传方式是移动端列表开发的通用规范
javascript·react native·react.js·ecmascript·harmonyos
jin1233226 小时前
React Native鸿蒙跨平台剧本杀组队消息与快捷入口组件,包含消息列表展示、快捷入口管理、快捷操作触发和消息详情预览四大核心功能
javascript·react native·react.js·ecmascript·harmonyos
烬头88218 小时前
React Native鸿蒙跨平台实现二维码联系人APP(QRCodeContactApp)
javascript·react native·react.js·ecmascript·harmonyos
pas1368 小时前
40-mini-vue 实现三种联合类型
前端·javascript·vue.js
摇滚侠8 小时前
2 小时快速入门 ES6 基础视频教程
前端·ecmascript·es6
2601_949833398 小时前
flutter_for_openharmony口腔护理app实战+预约管理实现
android·javascript·flutter
珑墨8 小时前
【Turbo】使用介绍
前端
军军君019 小时前
Three.js基础功能学习十三:太阳系实例上
前端·javascript·vue.js·学习·3d·前端框架·three