教程【免费下载链接】InterviewGuide「InterviewGuide」是阿秀从校园-职场多年计算机自学过程的记录以及学弟学妹们计算机校招秋招经验总结文章的汇总包括但不限于C/C 、Golang、JavaScript、Vue、操作系统、数据结构、计算机网络、MySQL、Redis等学习总结坚持学习持续成长项目地址https://gitcode.com/gh_mirrors/in/InterviewGuide点击查看免费下载本文基于 InterviewGuide 仓库中「精选力扣 300 题目之数组」这一章节目录文档与 22 道已整理题目的完整解法笔记展开系统介绍数组题型的核心技巧体系双指针、前缀和、计数哈希、贪心、模拟并对其中 10 道代表性题目逐题深入完整题面、作者多个版本的迭代解法代码、指针移动规则的严格证明与复杂度分析。读完本文你可以掌握一套从暴力解到最优解逐步迭代的数组刷题方法论并能按仓库内的文件链接直接查阅全部 22 道题的原始笔记。一、章节定位与练习清单在 InterviewGuide 的刷题体系中数组是 LeetCode 专题的第一个分类与字符串、链表、数学、哈希表、二分查找、栈、双指针、贪心、回溯、动态规划、DFS、树等 14 个专题并列见 LeetCode 专题总目录。数组章节的原始目录文档为 introduce.md按难度组织为三层Easy20 题位于easy/子目录覆盖前缀和、双指针、模拟、贪心、计数统计等基础套路Medium2 题位于medium/子目录重点讲解双指针的严格证明与取余对称计数Hardhard.md 中作者注明正在加班加点整理当中属于待补全部分。Easy 完整题目清单题号题目核心考点笔记文件414第三大的数单遍扫描维护 Top-3笔记581最短无序连续子数组双向扫描记录边界笔记605种花问题区间模拟 连续零计数笔记628三个数的最大乘积排序 / 单遍取极值笔记643子数组最大平均数 I固定窗口前缀和笔记665非递减数列贪心判断修改哪个元素笔记674最长连续递增序列单遍状态机笔记697数组的度计数 最小子数组笔记7171 比特与 2 比特 字符按位扫描笔记724寻找数组的中心索引总和变换 / 前缀和笔记747至少是其他数字两倍的最大数排序 / 双变量扫描笔记830较大分组的位置连续分组统计笔记840矩阵中的幻方枚举 幻方校验笔记849到最近的人的最大距离连续零段分类讨论笔记888公平的糖果交换差值映射笔记914卡牌分组计数 GCD笔记941有效的山脉数组双端爬山扫描笔记989数组形式的整数加法数位模拟 进位笔记1089复写零原地修改 / 栈笔记1128等价多米诺骨牌对的数量自定义 Key 哈希笔记剑指 Offer 66构建乘积数组左右乘积数组笔记Medium 完整题目清单题号题目核心考点笔记文件11盛最多水的容器双指针 短板收窄证明笔记1497检查数组对是否可以被 k 整除取余对称计数贪心笔记每道题的笔记都遵循统一结构题面与示例、一个或多个迭代版本的 C 解法附作者当时的提交执行用时与内存消耗记录、部分题目附有作者对官方题解或他人解法的转述与点评。这一多版本迭代的写法正是本章节最有价值的部分它展示的不是标准答案而是解题思维如何一步步收敛到最优解。二、数组章节的核心技巧体系通读 22 道题的解法后可以归纳出四类主干技巧后面会逐题展开双指针两指针从两端向中间收窄通过可证明的安全丢弃规则把 O(n²) 降到 O(n)。典型题11 盛最多水的容器Medium。前缀和 / 总和变换把子区间求和转化为两次全量求和的差值。典型题724 寻找数组的中心索引、643 子数组最大平均数 I、643/605 等连续段问题。计数 / 取余对称利用余数 r 与余数 k-r 必须成对这一对称性做 O(n) 判定。典型题1497 检查数组对是否可以被 k 整除、914 卡牌分组、1128 等价多米诺骨牌对的数量。单遍扫描维护状态模拟 / 贪心一次遍历中维护最大值、最小值、连续段长度、Top-3 等有限状态。典型题414 第三大的数、581 最短无序连续子数组、849 到最近的人的最大距离、665 非递减数列。三、代表题目详解3.1 LeetCode 11盛最多水的容器Medium双指针与严格证明题面给定 n 个非负整数 a1, a2, ..., an每个数代表坐标中的一个点 (i, ai)。在坐标内画 n 条垂直线垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线使得它们与 x 轴共同构成的容器可以容纳最多的水。说明不能倾斜容器且 n 至少为 2。示例输入[1,8,6,2,5,4,8,3,7]输出49。第一版暴力双重循环。枚举所有 (i, j) 组合面积 宽度 (j-i) × 短板高度 min(height[i], height[j])作者当时的提交记录为 1640 ms击败 9.51%1640ms 的耗时说明 O(n²) 在大数据量下不可接受int maxArea(vectorint height) { int len height.size(); int mostWater 0; for (int i 0, row, col; i len; i) { for (int j i 1; j len; j) { row j - i; col min(height[i], height[j]); mostWater row * col mostWater ? row * col : mostWater; } } return mostWater; }第二版双指针。左右指针夹住底边每次把短板向中间收窄一格提交记录提升到 16 ms击败 97.32%int maxArea(vectorint height) { int high height.size() - 1, low 0; int mostWater 0, temp; while (low high) { temp (high - low) * min(height[low], height[high]); mostWater mostWater temp ? mostWater : temp; if (height[low] height[high]) low; else high--; } return mostWater; }指针移动规则为什么成立笔记中给出的证明源自题解可以这样理解设当前状态面积为 S(i, j) min(h[i], h[j]) × (j - i)。无论移动哪一端底边宽度都减少 1若向内移动短板短板高度 min(h[i], h[j]) 可能变大遇到更高的板面积可能增大值得探索若向内移动长板短板高度不变或变小而宽度同时减少下一个面积一定小于当前面积因此这些状态可以被安全丢弃。换个角度不指定移动规则时状态数为 C(n, 2)即暴力枚举全部状态而在 S(i, j) 下向内移动短板设 h[i] h[j]到 S(i1, j)相当于一次性消去了 {S(i, j-1), S(i, j-2), ..., S(i, i1)} 这一组状态——这些状态的短板高度不超过 h[i]、底边宽度不超过 (j-i)面积必然 ≤ S(i, j)所以每次收窄短板永远不会丢掉全局最大值。复杂度时间 O(N)双指针最多遍历底边 N 次空间 O(1)。这道题的价值在于它是双指针为什么合法的标准教学样例不是启发式地贪心而是每一步都证明被跳过状态不可能更优。3.2 LeetCode 1497检查数组对是否可以被 k 整除Medium取余对称计数题面给你一个整数数组arr和一个整数k数组长度为偶数 n。需要把数组恰好分成 n/2 对使每对数字的和都能被 k 整除存在这样的分法返回 True否则返回 False。示例输入arr [1,2,3,4,5,10,6,7,8,9], k 5 输出true 解释划分后的数字对为 (1,9),(2,8),(3,7),(4,6) 以及 (5,10) 。输入arr [1,2,3,4,5,6], k 7 输出true 解释划分后的数字对为 (1,6),(2,5) 以及 (3,4) 。输入arr [1,2,3,4,5,6], k 10 输出false 解释无法在将数组中的数字分为三对的同时满足每对数字和能够被 10 整除的条件。约束条件1 n 10^5n 为偶数-10^9 arr[i] 10^91 k 10^5。注意取值范围包含负数这是本题最容易踩的坑。作者先记录了错误思路找到两个之和整除就配对——可能找不全、会漏配再给出正确思路对每个数求余统计余数频次余数 0 的个数必须是 2 的倍数只能与同为 0 的配对如 07、714其余数 r 的个数必须与余数 k-r 的个数相同1 配 k-1、2 配 k-2依此类推。bool canArrange(vectorint arr, int k) { vectorint res(k, 0); for (auto a : arr) { res[(a % k k) % k]; // 可能会有负数因此要加上 k } if (res[0] % 2 ! 0) return false; // 余数为 0 的必须是 2 的倍数比如 0 7 或者 7 14 这样的 for (int i 1; i k / 2; i) { if (res[i] ! res[k - i]) return false; } return true; }关键点有两个一是(a % k k) % k这个双重取余把负余数C 中a % k对负 a 得到负值归一化到 [0, k-1]二是校验只需扫到 k/2因为 r 与 k-r 是成对检查的扫一半即可。作者当时的提交记录为 264 ms击败 84.21%、61.5 MB击败 100%——内存消耗偏高的原因是开了长度为 k 的计数数组k 最大 10^5属于该题面下的正常量级。这道题的通用模式是配对使和满足整除类问题一律转成余数频次对称性检查。3.3 LeetCode 581最短无序连续子数组Easy三版迭代的双向扫描题面给定一个整数数组寻找一个连续子数组若对它升序排序后整个数组都变为升序要求子数组最短输出其长度。数组可能包含重复元素升序指非严格小于等于。示例输入[2, 6, 4, 8, 10, 9, 15]输出5只需对[6, 4, 8, 10, 9]排序。数组长度范围 [1, 10000]。作者的迭代路径很典型第一版参考他人思路24 ms击败 99.68%第二版获得启发后独立重写第三版把左右两次循环合并为一次单循环28 ms击败 98.19%。核心逻辑int findUnsortedSubarray(vectorint nums) { int len nums.size(), low 0, high len - 1, maxNum nums[0], minNum nums[len - 1]; for (int i 1; i len; i) { maxNum max(maxNum, nums[i]); minNum min(minNum, nums[len - 1 - i]); if (nums[i] maxNum) low i; if (nums[len - 1 - i] minNum) high len - 1 - i; } return low high ? low - high 1 : 0; }思路可以拆成两句从左到右记录前缀最大值当nums[i] maxNum时说明 i 已经落进无序区更新右边界 low从右到左记录后缀最小值当nums[i] minNum时说明 i 必须被纳入无序区更新左边界 high。两个循环共用一个下标 ilen-1-i即反向下标因此总时间 O(n)、空间 O(1)。判据low high的含义是从未触发过更新说明数组本来就有序返回 0。这类找乱序区间边界的题在面试中常作为前缀/后缀扫描的变体出现边界初始化和low/high的语义值得单独记牢。3.4 LeetCode 989数组形式的整数加法Easy三版迭代的数位模拟题面非负整数 X 的数组形式是每位数字从左到右形成的数组如 X1231 对应 [1,2,3,1]。给定 X 的数组形式 A返回 XK 的数组形式。示例输入A [1,2,0,0], K 34 输出[1,2,3,4] 解释1200 34 1234 输入A [2,7,4], K 181 输出[4,5,5] 解释274 181 455 输入A [2,1,5], K 806 输出[1,0,2,1] 解释215 806 1021 输入A [9,9,9,9,9,9,9,9,9,9], K 1 输出[1,0,0,0,0,0,0,0,0,0,0] 解释9999999999 1 10000000000约束1 A.length 100000 A[i] 90 K 10000A.length 1时A[0] ! 0。作者标注这是经典很经典的题目一步步渐进直到最优解法笔记保留了三版代码性能从 180 ms → 204 ms → 136 ms 演进。第一版180 ms击败 54.11%先把 K 拆成逆序数字数组 temp然后与 A 的尾部对齐逐位相加得到 res再单独处理进位超过 9 的位减 10 并向高位 1最高位溢出则 push_back(1)最后整体 reversevectorint addToArrayForm(vectorint A, int K) { vectorint temp, res; while (K ! 0) { temp.push_back(K % 10); K K / 10; } int i A.size() - 1, j 0; for (; i 0 j temp.size(); --i, j) { res.push_back(temp[j] A[i]); } if (j temp.size() i 0) { for (; i 0; --i) res.push_back(A[i]); } else if (i -1 j temp.size()) { for (; j temp.size(); j) res.push_back(temp[j]); } for (i 0; i res.size(); i) { if (res[i] 9) { res[i] res[i] - 10; if (i ! res.size() - 1) res[i 1] res[i 1] 1; else res.push_back(1); } } reverse(res.begin(), res.end()); return res; }第二版204 ms反而越改越慢把加法直接做进 temp 上省去 res 的一次构造但分支边界处理变复杂常数变大。这个越改越差的版本是本章笔记的诚实之处——优化不是单调的改结构可能引入额外分支开销。第三版136 ms击败 95.79%内存击败 92.20%原地复用 A——先把 A 逆序reverse(A.begin(), A.end())然后与 temp 逐位相加并边加边进位A[i] 9时减 10 且A[i1]若 i 是最后一位则A.push_back(1)分别处理temp 耗尽A 耗尽两种尾部情况后恢复顺序vectorint addToArrayForm(vectorint A, int K) { vectorint temp; while (K ! 0) { temp.push_back(K % 10); K K / 10; } reverse(A.begin(), A.end()); size_t i 0; for (; i A.size() i temp.size(); i) { A[i] temp[i] A[i]; if (A[i] 9 i ! A.size() - 1) { A[i] A[i] - 10; A[i 1] A[i 1] 1; } else if (A[i] 9 i A.size() - 1) { A[i] A[i] - 10; A.push_back(1); } } if (i temp.size()) { for (; i A.size(); i) { if (A[i] 9 i ! A.size() - 1) { A[i] A[i] - 10; A[i 1] A[i 1] 1; } if (A[i] 9 i A.size() - 1) { A[i] A[i] - 10; A.push_back(1); } } } else if (i A.size()) { for (; i temp.size(); i) A.push_back(temp[i]); } reverse(A.begin(), A.end()); return A; }这道题的通用教训大数加法不要想着转成整数A.length 可达 10000远超 64 位而是逆序对齐 逐位进位性能优化的空间在于避免第二份完整结果数组res → 原地复用 A以及把进位前移到加法循环内部减少一次全表扫描。3.5 LeetCode 1089复写零Easy原地修改的两种实现题面给定长度固定的整数数组 arr将其中每个零复写一遍其余元素向右平移且不能在超出原长度的位置写入要求就地修改不返回任何东西。示例[1,0,2,3,0,4,5,0]修改后为[1,0,0,2,3,0,0,4][1,2,3]保持不变。约束1 arr.length 100000 arr[i] 9。第一步实现48 ms击败 56.70%直接insert后pop_back()保长度注意i跳过刚插入的零void duplicateZeros(vectorint arr) { for (int i 0; i arr.size(); i) { if (arr[i] 0) { arr.insert(arr.begin() i, 0); arr.pop_back(); // 这步很关键 i; } } }问题在于vector::insert在中间位置会搬移其后所有元素每次命中零都是 O(n) 平移整体退化为 O(n²)。第二步实现28 ms击败 90.69%用栈预存前 length 个有效元素先只读扫描确定哪些位置保留遇到 0 则按两个位置计再整体弹出回填void duplicateZeros(vectorint arr) { stackint st; int temp 0; for (int i 0; i arr.size(); i) { st.push(arr[i]); temp; if (arr[i] 0) { if (temp arr.size()) break; temp; st.push(0); } if (temp arr.size()) break; } arr.clear(); while (!st.empty()) { arr.push_back(st.top()); st.pop(); } reverse(arr.begin(), arr.end()); }这个方案把随机位置的搬移变成了一次只读扫描 一次顺序回填空间 O(n)。如果要求严格 O(1) 额外空间标准做法是再扫一遍统计零的个数、确定有效前缀长度然后从后往前覆盖写——笔记中虽未展开该版本但本题笔记给出的两步演进已经足以说明就地修改题的通用取舍insert 的常数代价 vs 辅助容器的空间代价。3.6 LeetCode 1128等价多米诺骨牌对的数量Easyunordered_map 自定义 Key题面给定多米诺骨牌列表 dominoes若某张牌旋转 0 度或 180 度可得到另一张则等价形式上dominoes[i][a,b]与dominoes[j][c,d]等价当且仅当 ac 且 bd或 ad 且 bc。在 0 i j dominoes.length 前提下统计等价骨牌对 (i, j) 的数量。约束1 dominoes.length 400001 dominoes[i][j] 9。示例[[1,2],[2,1],[3,4],[5,6]]输出1。第一版双重循环逐一比较O(n²)n 可达 4 万时 TLEint numEquivDominoPairs(vectorvectorint dominoes) { int cut 0; for (int i 0; i dominoes.size(); i) { for (int j i 1; j dominoes.size(); j) { if ((dominoes[i][0] dominoes[j][0] dominoes[i][1] dominoes[j][1]) || (dominoes[i][0] dominoes[j][1] dominoes[i][1] dominoes[j][0])) cut; } } return cut; }第二版的关键突破是规范化把每张牌按 (min, max) 归一成标准键等价类问题就变成频次统计问题——每遇到一张新牌它与已有同类骨牌构成的对数就是该键当前频次累加后再自增。笔记中给出的实现演示了unordered_map如何以自定义 struct 作为 key需要同时提供哈希函数与判等函数struct KEY { int minNum; int maxNum; KEY(int f, int s) : minNum(f), maxNum(s) {} }; struct HashFunc { std::size_t operator()(const KEY key) const { using std::size_t; using std::hash; return ((hashint()(key.minNum) ^ (hashint()(key.maxNum) 1)) 1); } }; struct EqualKey { bool operator()(const KEY lhs, const KEY rhs) const { return lhs.minNum rhs.minNum lhs.maxNum rhs.maxNum; } }; int numEquivDominoPairs(vectorvectorint dominoes) { unordered_mapKEY, int, HashFunc, EqualKey unmp; int cut 0, maxNum 0, minNum 0; for (auto n : dominoes) { minNum min(n[0], n[1]); maxNum max(n[0], n[1]); if (unmp.find({minNum, maxNum}) ! unmp.end()) { cut unmp[{minNum, maxNum}]; unmp[{minNum, maxNum}]; } else { unmp[{minNum, maxNum}]; } } return cut; }作者记录该版 52 ms击败 87.56%并在第三版中参考他人写法进一步提到 48 ms击败 95.27%。这道题的教学价值在于 C 容器层面unordered_map的 key 默认只支持内置类型自定义 key 需要实现size_t operator()(const KEY) const与判等函数两个 functor而min/max 归一这一手让 O(n²) 的比较问题降为 O(n) 的哈希统计。3.7 LeetCode 665非递减数列Easy贪心决策改哪个题面给定长度为 n 的整数数组判断在最多改变 1 个元素的情况下能否变成非递减数列对所有 i 满足 array[i] array[i1]。示例[4,2,3]→ True把 4 改成 1[4,2,1]→ False。n 范围 [1, 10000]。作者第一版没做出来笔记保留了其尝试代码第二版32 ms击败 74.07%在解析启发下完成核心是判断发生冲突时应该改前一个还是当前这个bool checkPossibility(vectorint nums) { if (nums.size() 2) return true; int count 0; for (int i 1; i nums.size() count 2; i) { if (nums[i - 1] nums[i]) continue; count; // 前一个数大于当前值 if (i 2 nums[i - 2] nums[i]) nums[i] nums[i - 1]; else nums[i - 1] nums[i]; } return count 1; }笔记给出的解析把规律说得很清楚发现nums[i-1] nums[i]冲突后——若 i-2 位置不存在或nums[i-2] nums[i]说明可以放心把前一个较大的数改小改成 nums[i]若nums[i-2] nums[i]则前一个数改不动会破坏更前面的非递减关系只能把当前数改大改成 nums[i-1]。笔记中举的三个例子[4,2,3]、[-1,4,2,3]、[2,3,3,2,4]分别对应无前驱前驱可容纳必须改当前三种情形。实现上通过直接修改数组而非只计数让后续比较自动使用修正后的值避免了显式模拟。最多改一次类问题如 18 四数相加 II 之外的 665 族的通用模式就是遇到第一个冲突时做贪心决策第二次冲突即失败。3.8 LeetCode 724寻找数组的中心索引Easy总和变换题面返回数组中心索引——该索引左侧所有元素之和等于右侧所有元素之和不存在返回 -1多个则返回最靠左的。示例[1,7,3,6,5,6]输出 3左和 17311右和 5611[1,2,3]输出 -1。约束长度 [0, 10000]元素在 [-1000, 1000]。作者的解法20 ms击败 98.55%用一个恒等式把两次求和压成一次设全量和为 sum前缀和不含 i为 temp则temp sum - temp - nums[i]即中心索引。为避免乘法直接用temp * 2 sum - nums[i]判断int pivotIndex(vectorint nums) { int sum accumulate(nums.begin(), nums.end(), 0); int temp 0; for (int i 0; i nums.size(); i) { if (temp * 2 sum - nums[i]) { return i; } temp nums[i]; } return -1; }注意判断发生在temp nums[i]之前即 temp 严格表示i 左侧之和从 i0 开始扫描天然满足多个中心取最左的要求。这类子区间和与外部和比较的题中心索引、天平平衡点等都可以套用同一模板先算全量再线性推进前缀。3.9 LeetCode 414第三大的数Easy单遍维护 Top-3题面给定非空数组返回第三大的数不存在则返回最大值时间复杂度必须 O(n)。示例[3,2,1]→ 1[1,2]→ 2第三大不存在返回最大[2,2,3,1]→ 1注意是第三大且唯一出现的数两个 2 都排第二。作者的解法4 ms击败 99.23%用三个 long long 变量 firstNum/secondNum/thirdNum 初始化为 LONG_MIN单遍扫描维护降序 Top-3并依赖首尾严格比较自然去重int thirdMax(vectorint nums) { long long firstNum LONG_MIN, secondNum LONG_MIN, thirdNum LONG_MIN; for (auto a : nums) { if (firstNum a) { thirdNum secondNum; secondNum firstNum; firstNum a; } else if (firstNum a secondNum a) { thirdNum secondNum; secondNum a; } if (secondNum a thirdNum a) { thirdNum a; } } if (thirdNum LONG_MIN) return firstNum; else return thirdNum; }要点严格小于、的比较让重复值被自动忽略满足唯一出现语义哨兵 LONG_MIN 兼作未出现标记结束时 thirdNum 仍为哨兵则第三大不存在。Top-K 问题不排序、用 K 个变量单遍扫描的模式本题 O(n) 时间 O(1) 空间在 628 三个数的最大乘积取最大三个与最小两个、747 至少是其他数字两倍的最大数等题中反复出现是同章内可以互相印证的套路。3.10 剑指 Offer 66构建乘积数组Easy左右乘积两遍扫描题面给定数组 A[0..n-1]构建数组 B其中 B[i] A[0]×...×A[i-1]×A[i1]×...×A[n-1]即除自身外所有元素之积不能使用除法。示例输入[1,2,3,4,5]输出[120,60,40,30,24]。约束所有元素乘积不会溢出 32 位整数a.length 100000。作者把 O(n²) 暴力解法直接标注会超时舍弃留下的标准解法36 ms击败 88.82%只有七行核心代码B[i] 可以拆成左侧所有元素之积 × 右侧所有元素之积左乘积用一遍从左到右的累乘填充 B右乘积用一遍从右到左的累乘乘回 Bvectorint constructArr(vectorint a) { int len a.size(); int temp 1; vectorint b(len); for (int i 0; i len; temp * a[i], i) b[i] temp; temp 1; for (int i len - 1; i 0; temp * a[i], --i) b[i] * temp; return b; }第一遍结束时b[i]恰好是 A[0..i-1] 的乘积temp 在赋值后才乘入 a[i]保证不含自身第二遍把右半部分乘回去。时间 O(n)、空间 O(n)结果数组是前缀积 × 后缀积模板的原型题——凡除自身外聚合且禁用除法的问题都可以按此模板改写。四、刷题建议如何用好这一章笔记结合本章节笔记的写法特点给出三条可操作的练习建议按先 Easy 后 Medium的顺序做但优先做带多版本迭代的题。581、989、1089、1128、665、605 等题的笔记保留了两到三个版本的代码与各自的执行用时记录阅读时先只看题面自己想再对照第一版往往含 bug 或 TLE理解常见错误形态最后看最终版理解收敛点。比直接看标准答案更能建立题感。把每道题的技巧标签抄进自己的错题本。本章 22 题的技巧高度集中在四类双指针11、前缀/总和变换724、643、取余与计数对称1497、914、1128、单遍状态扫描414、581、849、665。同类题共享证明骨架如 11 题的收窄短板不丢最优论证按技巧聚类复习比按题号顺序复习效率高。留意题面约束里隐藏的坑位。1497 的负数取余、414 的唯一出现语义、1089 的原地且不越界写入、581 的重复元素下升序含等于这些都是作者笔记中实际踩过或专门标注的边界面试复述解法时把这些边界讲出来比只讲 happy path 更有说服力。全部 22 道题的原始笔记含作者各版本完整代码、提交性能记录与题解点评均可通过本文第一部分表格中的文件链接直达目录文档为 introduce.md。数组章节的 Hard 部分仍在整理中见 hard.md如需继续深入其他数据结构专题字符串、链表、动态规划等可参考 LeetCode 专题总目录。赞分享教程【免费下载链接】InterviewGuide「InterviewGuide」是阿秀从校园-职场多年计算机自学过程的记录以及学弟学妹们计算机校招秋招经验总结文章的汇总包括但不限于C/C 、Golang、JavaScript、Vue、操作系统、数据结构、计算机网络、MySQL、Redis等学习总结坚持学习持续成长项目地址https://gitcode.com/gh_mirrors/in/InterviewGuide点击查看免费下载相关推荐InterviewGuide LeetCode 栈专题11 道典型 Medium 题的 C 解法与迭代优化InterviewGuide LeetCode 栈专题11 道典型 Medium 题的 C 解法与迭代优化 本文基于 InterviewGuide 仓库中教程LeetCode 11. 盛最多水的容器从暴力枚举到双指针的经典数组题全解InterviewGuide 精选力扣 300 系列LeetCode 11. 盛最多水的容器从暴力枚举到双指针的经典数组题全解InterviewGuide 精选力扣 300 系列 本文来自 Intervi文档教程知识库InterviewGuide 刷题笔记LeetCode 532. 数组中的 K-diff 数对——从 O(n²) 暴力到排序 二分查找的进阶InterviewGuide 刷题笔记LeetCode 532. 数组中的 K diff 数对——从 O n² 暴力到排序 二分查找的进阶 本文是 Int文档教程知识库上一篇旧手柄重生指南XOutput如何让经典游戏设备在现代PC上畅玩下一篇如何用XOutput协议转换工具解决经典游戏手柄兼容性难题创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?