两数之和 ACM 版
把两数之和改成标准输入输出,重点练哈希表存已访问数字。
题单
每道题都能跳到图解动画,也能进入 OJ 直接提交;补满 100 道后仍按这套专题结构承载。
先练数组扫描、频次统计、前缀和与哈希表,把最常用的数据组织方式跑顺。
把两数之和改成标准输入输出,重点练哈希表存已访问数字。
候选人抵消模型,练习 O(1) 空间的多数元素查找。
统计前缀和出现次数,边扫边找 prefix - k。
把排序后的字符串作为 key,把同组单词收集到一起。
用哈希集合判断序列起点,只从最小起点向后延伸。
按左端点排序后维护当前合并区间的右边界。
把 k 对 n 取模后,用切片或三次翻转完成右轮转。
先乘左侧前缀,再从右向左累乘右侧后缀。
利用 x ^ x = 0 和 x ^ 0 = x,把所有数异或起来。
用三指针把 0 放左边、2 放右边,1 留在中间。
从右找第一个下降点,交换后把后缀反转成最小序。
把数组值看作指针走向,用环入口定位重复数字。
用 Map 维护访问顺序,淘汰最久未使用的键。
在标准输入输出中练习原地归位,重点想清每个正数应该待在哪个下标。
围绕左右边界、快慢指针和窗口收缩,训练一次遍历里的不变量。
用左右指针维护一个没有重复字符的窗口。
每次移动较短的板,练习双指针的不变量。
排序后固定第一个数,再用左右指针去重枚举。
慢指针指向下一个非零元素应该放的位置。
双指针维护左右最高墙,每次结算较矮一侧能接的水。
枚举每个中心向两边扩展,长度相同取更靠左的答案。
维护长度为 p 的窗口计数,计数一致时记录左端点。
右指针扩张满足需求后,左指针尽量收缩窗口。
练二维数组的行列标记、边界收缩、原地旋转和有序矩阵搜索。
覆盖排列、组合、子集、括号生成和网格搜索,重点练选择、撤销与剪枝。
按数字对应字符集逐层回溯,生成所有组合。
只在左括号数量不超 n、右括号不超左括号时继续搜索。
排序后从当前下标继续选择,允许重复使用同一个数字。
用 used 数组标记已选择元素,逐层构造排列。
每个位置都有选或不选两种选择,按递归顺序收集子集。
从每个格子作为起点做 DFS,同一路径中不能重复使用格子。
在标准输入输出中练习回溯切分,重点想清每一刀切在哪里。
在标准输入输出中练习按行放置皇后,重点记录列和两条对角线的占用。
把指针顺序、合并、反转和环形关系看清楚,再用 ACM 输入输出稳定复现。
用两个指针顺序归并两个升序序列。
用 prev、cur、next 三个指针保护链表不断链。
用数组模拟逆序链表,逐位相加并处理进位。
用快慢指针找到倒数第 n 个节点的前驱,再删除目标节点。
快指针一次走两步、慢指针一次走一步,相遇则有环。
ACM 版用数组模拟链表,重点核对归并排序后的有序结果。
两指针分别走完 A+B 与 B+A,相遇点就是交点。
找到中点后反转后半段,再与前半段逐个比较。
用 next 下标数组表达链表,真正检测环入口,而不是从输入直接读取答案。
在标准输入输出中练习成对重连指针,重点处理落单的最后一个节点。
在标准输入输出中练习分组翻转,重点接好每一组的头和尾。
在标准输入输出中练习深拷贝带随机指针的链表,重点建立原节点到新节点的对应。
练括号匹配、单调结构、Top K 和队列窗口,把进出顺序与候选维护想明白。
遇到左括号入栈,遇到右括号检查栈顶。
先计数,再按频率降序和数值升序输出前 K 个。
栈里保存还没找到更高温度的下标。
把每个链表当前元素放入小根堆,持续弹出最小值。
主栈存值,辅助栈同步存当前最小值。
队列中维护下标,保证对应值递减,队首就是窗口最大值。
遇到左括号入栈保存当前串和重复次数,右括号时展开。
单调递增栈中保存下标,弹栈时用当前下标确定右边界。
在标准输入输出中练习第 K 大,重点区分第 K 大与排序下标。
用失效边界和未匹配左括号下标,计算最长连续合法片段。
在标准输入输出中练习用两个堆维护中位数,重点保持两边数量平衡。
从层序遍历开始建立树题手感,再逐步进入递归、路径和树形 DP。
用队列逐层扩展节点,练习树的层序输出。
递归或栈模拟左根右顺序。
中序遍历必须严格递增,或递归维护上下界。
同时比较左子树的左/右与右子树的右/左。
最大深度等于左右子树最大深度加一。
前序首元素是根,在中序中切分左右子树递归构造。
按先序遍历顺序把节点接到右指针链上。
后序返回单边最大贡献,同时用左右贡献更新全局答案。
递归交换每个节点的左右子树。
后序递归,若左右子树分别找到目标,则当前节点就是 LCA。
DFS 时维护从根到当前节点的前缀和计数。
每个节点用左右子树深度之和更新最长路径边数。
层序遍历时记录每一层最后一个节点。
BST 的中序遍历是升序,第 k 个访问到的节点就是答案。
在标准输入输出中练习分治建树,重点选好每一段的根。
覆盖网格搜索、拓扑排序、并查集、最短路和多源 BFS,重点练建图与访问状态。
把边界、单调性和答案空间拆开练,避免只会套模板。
找第一个大于等于 target 的位置,就是插入位置。
把矩阵看成一条升序数组,对虚拟下标做二分。
分别找第一个大于等于 target 和第一个大于 target 的位置。
每次判断哪一半有序,再决定 target 落在哪一侧。
用右端点判断最小值在左半还是右半。
在较短数组上二分切分位置,让左右两侧数量和大小关系都成立。
从一维 DP、网格 DP、背包和股票状态机,过渡到能说清状态与转移。
维护以当前位置结尾的最大连续和。
把最后一步拆成迈 1 阶或 2 阶,得到斐波那契式转移。
一边扫价格,一边记录历史最低买入价。
每个位置只在抢和不抢之间做选择。
维护每个长度的最小结尾值,练习贪心加二分。
把金额当作状态,枚举最后使用的硬币。
维护当前能到达的最远位置,判断是否覆盖最后一个下标。
按层扩展当前跳跃范围,每到边界就增加一次跳跃。
每个格子的路径数等于上方和左方路径数之和。
原地或滚动数组维护从左上角走到每个格子的最小代价。
dp[i] 表示前 i 个字符能否由词典拼出。
把问题转成是否能凑出 sum / 2。
同时维护以当前位置结尾的最大乘积和最小乘积。
dp[i][j] 表示两个前缀的最长公共子序列长度。
把平方数当作物品,做最少个数的完全背包 DP。
每段右边界取段内字符最后出现位置的最大值。
通过操作序列实现 insert、search 与 startsWith,练清路径存在和单词结束标记的区别。
用插入、删除、替换三种转移求两个单词之间的最少操作数。
在标准输入输出中练习由上一行推出下一行,重点处理每行两端的 1。