两数之和。

你不用慌,刚开始刷 LeetCode 热题 100 连第一题(两数之和)都不会,是所有编程新手的常态,这不是你能力的问题,而是还没掌握「解算法题的基本思路」和「前端视角的解题方法」。我会从最基础的步骤带你拆解这道题,帮你建立「从 0 到 1 解算法题」的思维,而不是直接给答案。

第一步:先读懂「两数之和」的题目(LeetCode 1. 两数之和)

先把题目拆成「人话」,明确输入、输出、核心要求:

  • 输入 :一个整数数组 nums + 一个目标值 target
  • 输出 :数组中两个不同位置 的数的下标,这两个数相加等于 target
  • 要求:每个输入只有一个答案,同一个元素不能用两次。
  • 示例 :输入 nums = [2,7,11,15], target = 9 → 输出 [0,1](因为 2+7=9)。

第二步:从「最笨的方法」开始(新手先落地,再优化)

新手不要一上来就想「最优解」,先写「能跑通的代码」,再谈优化。这道题最容易理解的是「暴力枚举法」(两层循环):

思路
  1. 遍历数组中的每一个数 nums[i]
  2. 对于每个 nums[i],再遍历它后面的所有数 nums[j](j > i,避免重复);
  3. 检查 nums[i] + nums[j] 是否等于 target,如果是,直接返回 [i,j]
前端(JS)实现代码(带详细注释)

javascript

运行

javascript 复制代码
/**
 * @param {number[]} nums 输入的整数数组
 * @param {number} target 目标和
 * @return {number[]} 满足条件的两个数的下标
 */
var twoSum = function(nums, target) {
    // 第一层循环:遍历每个元素,i是第一个数的下标
    for (let i = 0; i < nums.length; i++) {
        // 第二层循环:遍历i后面的元素,j是第二个数的下标(避免重复用同一个元素)
        for (let j = i + 1; j < nums.length; j++) {
            // 核心判断:两数之和等于目标值
            if (nums[i] + nums[j] === target) {
                // 找到答案,直接返回下标数组
                return [i, j];
            }
        }
    }
    // 题目说必有解,这里只是兜底(实际不会执行)
    return [];
};

// 测试用例(新手一定要写测试,验证自己的代码)
console.log(twoSum([2,7,11,15], 9)); // 输出 [0,1]
console.log(twoSum([3,2,4], 6)); // 输出 [1,2]
console.log(twoSum([3,3], 6)); // 输出 [0,1]
代码解释(新手逐行看)
  • for (let i = 0; i < nums.length; i++):遍历数组的每一个元素,i 是第一个数的下标;
  • for (let j = i + 1; j < nums.length; j++)ji+1 开始,确保不会重复使用同一个元素(比如不会出现 i=0,j=0 的情况);
  • nums[i] + nums[j] === target:判断两数之和是否等于目标值,满足则返回下标;
  • 测试用例覆盖了「普通情况」「非相邻元素」「重复值」,验证代码的鲁棒性。
复杂度分析(大厂面试必说)
  • 时间复杂度:O(n2)(n 是数组长度),因为两层循环,最坏情况要遍历 n∗(n−1)/2 次;
  • 空间复杂度:O(1),只用到了几个变量,没有额外开辟大空间。

第三步:优化解法(前端高频考的「哈希表法」)

暴力法虽然好理解,但效率低(O(n2)),大厂面试会追问「能不能优化?」,这时候要讲「哈希表(Map)」的解法(时间复杂度 O(n))。

思路(新手记这个「核心逻辑」)
  1. 用一个 Map 来「存已经遍历过的数 + 它的下标」(空间换时间);
  2. 遍历数组时,对当前数 nums[i],计算「需要找的补数」:complement = target - nums[i]
  3. 检查 Map 里有没有这个补数:
    • 如果有,说明之前遍历过这个补数,直接返回「补数的下标」和「当前下标 i」;
    • 如果没有,把当前数 nums[i] 和下标 i 存入 Map,继续遍历。
JS 实现代码(带注释)

javascript

运行

javascript 复制代码
var twoSum = function(nums, target) {
    // 1. 创建一个Map,用来存「已遍历的数: 下标」
    const map = new Map();
    // 2. 遍历数组,i是当前下标,num是当前数
    for (let i = 0; i < nums.length; i++) {
        const num = nums[i];
        // 3. 计算需要找的补数
        const complement = target - num;
        // 4. 检查Map里有没有这个补数
        if (map.has(complement)) {
            // 有则返回:补数的下标 + 当前下标
            return [map.get(complement), i];
        }
        // 5. 没有则把当前数和下标存入Map
        map.set(num, i);
    }
    // 兜底返回(题目保证有解)
    return [];
};

// 测试用例
console.log(twoSum([2,7,11,15], 9)); // [0,1]
console.log(twoSum([3,2,4], 6)); // [1,2]
console.log(twoSum([3,3], 6)); // [0,1]
核心解释(新手重点理解)
  • Map 的作用:把「找补数」的操作从「遍历数组(O (n))」变成「查 Map(O (1))」;
  • 为什么不会重复?因为先查补数,再存当前数,所以当前数不会和自己匹配(比如 nums=[3,3],遍历第一个 3 时,Map 为空,存入 Map;遍历第二个 3 时,补数是 3,Map 里有第一个 3 的下标 0,直接返回 [0,1]);
  • 复杂度:时间 O(n)(只遍历一次),空间 O(n)(最坏情况存 n-1 个数)。

第四步:新手刷这道题的「正确姿势」(比会写更重要)

  1. 先抄再理解:如果完全不会,先把暴力法的代码抄一遍,逐行改测试用例(比如把 nums 改成 [1,2,3],target 改成 5),看输出是否正确,理解每一行的作用;
  2. 自己写一遍:关掉答案,自己写暴力法,写完后用测试用例验证,遇到 bug(比如 j 从 0 开始导致重复),自己排查;
  3. 思考优化点:问自己「为什么暴力法慢?」「哪里可以省时间?」,再尝试写哈希表法;
  4. 复盘总结:这道题的核心是「空间换时间」,哈希表是前端解「数组 / 字符串匹配」的高频工具,记住这个思路(比如后续刷「字母异位词」「两数之和变种题」都能用)。

第五步:给你的「新手刷题小建议」(针对热题 100)

  1. 不要跳题:热题 100 是按「基础→进阶」排的,第一题是最基础的哈希表应用,吃透它再刷下一题(比如第二题两数相加是链表题,先把数组 / 哈希表的基础打牢);

  2. 每天只刷 1 道:新手不用贪多,每天把 1 道题的「暴力法 + 最优解」都搞懂,手写 2 遍,比一天刷 5 道半懂不懂的题有用;

  3. 记「模板」不记答案 :这道题的哈希表模板可以记下来:

    javascript

    运行

    javascript 复制代码
    // 哈希表解题模板(数组匹配类)
    const map = new Map();
    for (let i = 0; i < arr.length; i++) {
        const need = target - arr[i];
        if (map.has(need)) {
            return [map.get(need), i];
        }
        map.set(arr[i], i);
    }
  4. 用前端语言写:全程用 JS/TS 写,不用纠结 Python/Java 的写法,大厂前端面试只看你用前端语言的实现。

总结

  1. 新手不会第一题完全正常,核心是先从「暴力法」落地,再理解「最优解」,不要一开始就追求完美;
  2. 「两数之和」的核心考点是哈希表的空间换时间思想,这是前端算法的高频考点,必须吃透;
  3. 刷题的关键是「理解 + 手写 + 复盘」,而不是背答案,哪怕一天只搞懂 1 道题,也是有效进步。

什么是哈希表

哈希表(Hash Table)其实是前端开发中天天都在用的东西,只是你可能没意识到它的名字而已。我会用最通俗的比喻 + 前端实际例子,帮你彻底搞懂哈希表,以及它在「两数之和」里的作用。

第一步:先理解「哈希表」的核心概念(用生活例子比喻)

哈希表的本质是「键值对(Key-Value) 存储结构」,核心作用是:通过「键(Key)」快速找到「值(Value)」,就像我们生活中的「字典」或「通讯录」:

  • 字典:通过「汉字(Key)」快速查到「释义(Value)」,不用从头翻;
  • 通讯录:通过「名字(Key)」快速找到「手机号(Value)」,不用一个个找;
  • 哈希表:通过「自定义的键」快速找到「对应的值」,时间复杂度接近 O(1)(瞬间找到)。
对比:为什么哈希表比「遍历数组」快?
  • 遍历数组找值:比如在 [2,7,11,15] 里找 7,需要从头数(第 2 个),最坏要找完整个数组(O(n));
  • 哈希表找值:把数组存成 {2:0, 7:1, 11:2, 15:3},找 7 的话直接查 哈希表[7],一步到位(O(1))。

第二步:前端里的「哈希表」就是这些东西

在 JavaScript 中,我们不用自己实现哈希表,直接用现成的「对象(Object)」或「Map」就行 ------ 这两个都是哈希表的具体实现:

前端哈希表载体 特点 常用场景
Object(对象) 键只能是字符串 / 数字 / Symbol 简单场景(比如存数字、字符串键)
Map 键可以是任意类型(数字、对象、函数等),有专门的 API(has/set/get) 算法题 / 复杂场景(推荐用)
举个前端实际例子(先感受用法)

javascript

运行

javascript 复制代码
// 1. 用Object模拟哈希表(存「数:下标」)
const objMap = {};
// 存值:键是数字2,值是下标0
objMap[2] = 0;
// 取值:通过键2,瞬间拿到值0
console.log(objMap[2]); // 输出 0
// 检查是否有某个键
console.log(2 in objMap); // 输出 true

// 2. 用Map(算法题更推荐,语义更清晰)
const map = new Map();
// 存值:set(键, 值)
map.set(7, 1);
// 取值:get(键)
console.log(map.get(7)); // 输出 1
// 检查是否有某个键:has(键)
console.log(map.has(7)); // 输出 true
// 删除键:delete(键)
map.delete(7);
console.log(map.has(7)); // 输出 false

第三步:回到「两数之和」,理解哈希表的作用

我们再回头看「两数之和」的优化解法,就能明白哈希表到底在干嘛:

问题核心痛点(暴力法的问题)

暴力法要两层循环,是因为对每个数 nums[i],都要「遍历剩下的数」找 target - nums[i](补数),这个找的过程是 O(n),所以整体是 O(n2)。

哈希表的解决思路(空间换时间)

我们把「已经遍历过的数和它的下标」存到哈希表里,这样找补数的过程就从「遍历数组」变成「查哈希表」(O(1)),整体时间复杂度降到 O(n)。

用「通讯录」比喻这一过程

假设:

  • 目标和 target = 9;
  • 数组 nums = [2,7,11,15];
  • 哈希表 = 你的「通讯录」,存的是「数:下标」。

遍历过程:

  1. 遍历第一个数 2(下标 0):
    • 补数 = 9 - 2 = 7;
    • 查通讯录:有没有 7?没有;
    • 把 2 和下标 0 存进通讯录(通讯录:{2:0});
  2. 遍历第二个数 7(下标 1):
    • 补数 = 9 - 7 = 2;
    • 查通讯录:有 2!对应的下标是 0;
    • 直接返回 [0,1],结束。
再看代码,就完全懂了

javascript

运行

javascript 复制代码
var twoSum = function(nums, target) {
    // 1. 初始化哈希表(空通讯录)
    const map = new Map();
    // 2. 遍历数组(一个个看数)
    for (let i = 0; i < nums.length; i++) {
        const num = nums[i]; // 当前数
        const complement = target - num; // 补数(要找的数)
        
        // 3. 查哈希表:有没有这个补数?
        if (map.has(complement)) {
            // 有就返回:补数的下标 + 当前下标
            return [map.get(complement), i];
        }
        // 4. 没有就把当前数和下标存进哈希表
        map.set(num, i);
    }
    return [];
};

第四步:新手必懂的哈希表核心考点(前端算法)

  1. 核心优势:「查询 / 插入 / 删除」的平均时间复杂度都是 O(1),这是它能优化算法的关键;

  2. 前端算法常见用法

    • 计数(比如统计数组中每个数出现的次数);
    • 去重(比如数组去重,存到 Map/Set 里);
    • 快速匹配(比如两数之和、字母异位词);
    • 缓存(比如存已经计算过的结果,避免重复计算);
  3. 和数组的区别

    操作 数组 哈希表(Map)
    按值找下标 O(n) O(1)
    按下标找值 O(1) 不支持(哈希表没有下标)
    存储结构 有序(下标) 无序(ES6 的 Map 是有序的,但算法题不关注)

总结

  1. 哈希表的核心是「键值对存储」,能通过键快速找到值 (O(1)),前端用 ObjectMap 实现;
  2. 在「两数之和」中,哈希表的作用是「存已遍历的数和下标」,把找补数的时间从 O(n) 降到 O(1),实现算法优化;
  3. 哈希表是前端算法的「高频工具」,只要遇到「需要快速查找 / 匹配」的场景,优先想到它。

为什么哈希表比数组快,不应该都是从头开始找吗

你这个问题问到了哈希表的核心原理上!很多新手都会有这个疑问 ------「哈希表看起来也是存了一堆键值对,为什么找 7 不用从头遍历?」其实关键在于哈希表的「哈希函数」和「存储结构」,和数组的遍历完全不是一回事。我用最通俗的方式给你讲明白,不用看复杂的公式,只理解核心逻辑就行。

第一步:先推翻「哈希表需要从头找」的误区

数组的存储是「连续的内存地址」,比如 [2,7,11,15] 存的时候是按顺序放在内存里:

  • 下标 0 → 地址 A → 存 2
  • 下标 1 → 地址 A+1 → 存 7
  • 下标 2 → 地址 A+2 → 存 11所以找 7 的时候,只能从地址 A 开始一个个查,直到找到地址 A+1,这就是「遍历」(O (n))。

而哈希表(比如 JS 的 Object/Map)的存储逻辑完全不同:它不是按顺序存,而是通过「哈希函数」把键(比如 7)直接转换成一个内存地址,存的时候直接放到这个地址,查的时候也直接用这个地址取 ------ 相当于给每个键分配了一个「专属储物柜」,找的时候不用挨个翻,直接去对应的柜子拿就行。

第二步:用「快递柜」比喻哈希表的核心逻辑

我们用生活中的「快递柜」来比喻,你一下就能懂:

  1. 存快递(存键值对)
    • 你有一个快递(键 = 7,值 = 1),快递柜有个「编码规则」(哈希函数):键的数字 % 10(取余)就是柜号;
    • 计算 7 % 10 = 7 → 直接把快递放进 7 号柜;
    • 同理,2 → 2 号柜,11 → 1 号柜,15 →5 号柜。
  2. 取快递(查值)
    • 要找键 7 对应的值,不用从 1 号柜翻到 10 号柜;
    • 直接用编码规则算:7%10=7 → 打开 7 号柜,直接拿到快递(值 = 1);
    • 整个过程只有「计算柜号 + 开柜」两步,和有多少个快递无关 ------ 这就是 O (1)(常数时间)。
对比数组的「货架」逻辑:

数组是「一排货架」,找 7 的时候要从第一个货架开始数:1 号(2)→2 号(7),数到第二个才找到,货架越长,数的次数越多(O (n))。

第三步:回到 JS 的哈希表(Object/Map),看实际逻辑

JS 里的 Object/Map 底层就是用这个原理实现的(细节比快递柜复杂,但核心一致):

  • 当你执行 map.set(7, 1) 时:JS 引擎会用「哈希函数」把键 7 转换成一个哈希值(比如一串数字),然后把值 1 存在这个哈希值对应的内存位置;
  • 当你执行 map.get(7) 时:不会遍历所有键,而是再次用同一个哈希函数算出 7 的哈希值,直接去对应的内存位置取值 ------ 不管 Map 里有 10 个还是 1000 个键值对,这个过程都是「一次计算 + 一次取值」,时间复杂度就是 O (1)。

第四步:补充一个小细节(哈希冲突)

你可能会问:如果两个键的哈希值一样怎么办?比如键 7 和 17,按「%10」的规则都对应 7 号柜(这叫「哈希冲突」)。其实哈希表有解决冲突的办法(比如「链表法」):7 号柜里放一个小链表,先存 7→1,再存 17→2,查的时候到 7 号柜后,只需要遍历这个小链表(通常只有 1-2 个元素),整体还是接近 O (1),远快于遍历整个数组。

用代码验证:哈希表查值和数组查值的效率差异

我们用 10 万条数据做对比,你能直观看到区别:

javascript

运行

javascript 复制代码
// 1. 准备数据:10万个数字的数组 + 对应的哈希表
const nums = [];
const hashMap = new Map();
for (let i = 0; i < 100000; i++) {
    nums.push(i);
    hashMap.set(i, i);
}

// 2. 数组找值(找99999):需要遍历10万次
console.time('数组查找');
const index = nums.findIndex(item => item === 99999);
console.timeEnd('数组查找'); // 耗时约几毫秒(随数据量增长)

// 3. 哈希表找值(找99999):一次到位
console.time('哈希表查找');
const value = hashMap.get(99999);
console.timeEnd('哈希表查找'); // 耗时约0.01毫秒(几乎不随数据量增长)

运行后你会发现:数组查找的耗时会随着数据量增加而明显变长,而哈希表几乎不变 ------ 这就是 O (n) 和 O (1) 的本质区别。

总结

  1. 哈希表查值不用从头遍历,核心是通过「哈希函数」把键直接转换成存储地址,查值时直接取对应地址的值;
  2. 数组是「顺序存储 + 下标访问」,按值找下标必须遍历;哈希表是「哈希地址存储 + 键访问」,按键找值一步到位;
  3. 「两数之和」用哈希表优化的核心,就是把「遍历数组找补数(O (n))」换成「哈希表查补数(O (1))」,从而把整体时间复杂度从 O (n²) 降到 O (n)。

哈希函数、哈希冲突这两个哈希表的核心细节,用「快递柜」的比喻继续讲透,还是保持通俗不绕公式,同时补充前端算法题里用得到的知识点,面试被追问也能答上来~

一、哈希函数:哈希表的「快递柜编码规则」

哈希函数(Hash Function)是哈希表的核心 ,作用就是把任意类型的「键(Key)」,转换成一个固定长度的「哈希值(Hash Code)」,这个哈希值就是键在哈希表中的「存储地址标识」。

1. 核心要求(算法题 / 面试只记这 3 点)
  • 确定性:同一个键,永远算出同一个哈希值(比如键 7,每次算都是 7,不能这次 7 下次 8);
  • 高效性:计算速度要快,不能比遍历数组还慢;
  • 均匀性:计算出的哈希值要均匀分布,尽量避免多个键算出同一个值(减少冲突)。
2. 举个前端能懂的「简易哈希函数」例子

算法题里我们接触的键大多是数字 / 字符串,用简单的算法就能做哈希函数,比如:

  • 键是数字 :直接取余(key % 数组长度),比如键 7、17、27,对 10 取余,得到 7、7、7(这就是后面要讲的冲突);
  • 键是字符串 :比如键"abc",可以把每个字符的 ASCII 码相加再取余,a(97)+b(98)+c(99)=294,对 10 取余得 4,哈希值就是 4。
3. JS 里的哈希函数(不用自己实现,了解即可)

我们写算法题用的Map/Object,JS 引擎已经帮我们实现了高效的哈希函数:

  • 数字 / 字符串 / Symbol:直接生成唯一哈希值;
  • 对象 / 数组 :根据内存地址生成哈希值(所以两个内容相同的空对象{} !== {},哈希值不同,Map 里会当成两个键)。✅ 前端算法题小技巧 :如果需要用对象当 Map 的键,先把对象转成字符串(比如JSON.stringify(obj)),避免因内存地址导致的哈希值不同。

二、哈希冲突:多个快递「撞柜」了怎么办?

不管哈希函数设计得多好,必然会出现「不同的键算出同一个哈希值」的情况 ,这就是哈希冲突 ------ 比如按key%10的规则,键 7 和 17 都算出 7,都要放 7 号快递柜,这就是撞柜了。

1. 为什么冲突不可避免?

核心是「鸽巢原理」:比如有 10 个快递柜(哈希值范围 0-9),但要存 11 个快递,必然有至少一个柜子要放 2 个快递,哈希表的哈希值范围是固定的,而键的数量是无限的,冲突是必然的。

2. 哈希表解决冲突的两种核心方法(面试高频,记名字 + 思路)

哈希表的底层实现,主要用这两种方法解决冲突,前端算法题不用实现,但要能说清思路,大厂面试偶尔会追问「哈希表怎么解决冲突?」

方法 1:链地址法(拉链法)------ 快递柜里「加层板」

这是最常用 的方法,也是 JSMap/Object底层用的方法,思路超简单:

  • 把哈希表的每个存储位置(快递柜),变成一个链表 / 数组
  • 当多个键哈希值相同时,就把这些键值对依次存到同一个位置的链表中(相当于快递柜里加层板,一层放一个快递)。

用快递柜比喻链地址法

  • 规则:key%10,柜号 0-9;
  • 存键 7(值 1):7 号柜空,直接放进去,7 号柜→[7:1]
  • 存键 17(值 2):哈希值也是 7,7 号柜加层板,7 号柜→[7:1, 17:2]
  • 存键 27(值 3):继续加层板,7 号柜→[7:1, 17:2, 27:3]
  • 查值:找 17 时,先算哈希值 7→打开 7 号柜→遍历柜内的小链表,找到 17 对应的值 2。

✅ 关键:链地址法的查询效率依然接近 O (1),因为哈希函数的均匀性,每个柜子里的链表都很短(通常 1-2 个元素),遍历的代价可以忽略。

方法 2:开放寻址法 ------ 撞柜了就「找隔壁空柜子」

思路:当某个位置被占了,就按一定规则依次查找下一个空的存储位置,把键值对存进去,常见的规则是「线性探测」(往后找 1 个,再找 1 个)。

用快递柜比喻开放寻址法

  • 规则:key%10,柜号 0-9;
  • 存键 7(值 1):7 号柜空,直接放,7 号柜→7:1
  • 存键 17(值 2):7 号柜被占,找隔壁 8 号柜,空的,存 8 号柜→17:2
  • 存键 27(值 3):7 号、8 号都被占,找 9 号柜,空的,存 9 号柜→27:3
  • 查值:找 17 时,先算 7 号柜→没有→找 8 号柜→找到 17:2。

❌ 缺点:如果哈希表存得很满,会出现「连续占柜」的情况,查询时要找很多次,效率会降到 O (n),所以开放寻址法的哈希表不能存太满

三、前端算法题里,哈希表的这些细节不用纠结!

讲完哈希函数和冲突,你可能会担心「刷题时要不要考虑这些?」,答案是完全不用,因为:

  1. JS 的Map/Object已经帮我们实现了「高效哈希函数 + 链地址法解决冲突」,我们只用调用set/get/has就行,不用关心底层;
  2. 算法题里考察的是哈希表的使用思路(空间换时间),不是底层实现,面试官也不会让前端手写哈希表;
  3. 我们刷的题中,哈希表的查询效率都可以直接按O(1) 算,不用考虑冲突的遍历代价。

四、哈希表核心知识点总结(面试答题版)

如果面试被追问「哈希表的原理」,把这几句按顺序说,简洁又到位,完全够前端的考察要求:

  1. 哈希表的核心是键值对存储 ,通过哈希函数把键转换成哈希值,作为存储地址,实现按键的 O (1) 查询;
  2. 由于鸽巢原理,哈希冲突不可避免,常用链地址法(拉链法) 解决,将冲突的键值对存到同一个地址的链表中;
  3. 前端中用Object/Map实现哈希表,Map 支持任意类型的键,解决了 Object 键只能是字符串 / 数字的问题,算法题中更推荐用 Map。

最后再回到「两数之和」,串一遍完整逻辑

现在你懂了底层,再看这道题的哈希表解法,就是完整的逻辑链了:

  1. 初始化 Map(空的哈希表,有自己的哈希函数和冲突解决机制);
  2. 遍历数 7,计算补数 2→调用map.has(2)→Map 内部用哈希函数算出 2 的哈希值→找到对应地址→地址为空,返回 false;
  3. 调用map.set(7,1)→Map 用哈希函数算出 7 的哈希值→存到对应地址;
  4. 遍历数 2,计算补数 7→调用map.has(7)→算出 7 的哈希值→找到对应地址→地址里有 7:1,返回 true→调用map.get(7)拿到 1,返回 [1,0]。

到这里,哈希表的核心原理就全懂了,从「怎么用」到「为什么快」再到「底层细节」,完全覆盖前端算法题和面试的要求~

相关推荐
wen__xvn2 小时前
代码随想录算法训练营DAY27第八章 贪心算法 part01
算法·贪心算法
We་ct2 小时前
LeetCode 125. 验证回文串:双指针解法全解析与优化
前端·算法·leetcode·typescript
客卿1232 小时前
力扣20-有效括号(多家面试题)
算法·leetcode·职场和发展
木井巳2 小时前
【递归算法】快速幂解决 pow(x,n)
java·算法·leetcode·深度优先
Maỿbe3 小时前
重走力扣hot的矩阵
算法·leetcode·矩阵
朔北之忘 Clancy3 小时前
2025 年 12 月青少年软编等考 C 语言二级真题解析
c语言·开发语言·c++·学习·算法·青少年编程·题解
2301_790300963 小时前
C++与增强现实开发
开发语言·c++·算法
每天要多喝水3 小时前
贪心算法专题Day18
算法·贪心算法
毅炼4 小时前
hot100打卡——day14
java·数据结构·算法·leetcode·ai·深度优先·哈希算法