一、数学问题
50. Pow(x, n)
-
思路:利用快速幂算法,将指数分解为二进制位,通过位运算逐位处理。若指数为负数,先转化为正数计算,结果取倒数。
-
关键点:位运算优化(
n & 1判断奇偶,n >>= 1右移),处理int负数溢出(用long存储指数)。
66. 加一
-
思路:从数组末位开始处理进位,若末位非9则直接加一;若全为9,创建长度+1的新数组,首位为1。
-
关键点:循环处理进位,处理全9的边界情况。
69. x的平方根
-
思路:二分查找法,在
[0, x]范围内查找最大整数m,使得m² ≤ x,处理整数溢出(用long计算)。 -
关键点:二分模板(
left <= right),返回right作为结果。
二、字符串处理
3. 无重复字符的最长子串
-
思路:滑动窗口+哈希集合,右指针扩展窗口,左指针收缩至无重复字符,记录最大窗口长度。
-
关键点:
HashSet存储窗口内字符,处理重复时左指针移动并移除重复字符。
5. 最长回文子串
-
思路:中心扩展法,以每个字符为中心向两侧扩展,比较奇数和偶数长度的回文串,记录最长子串。
-
关键点:双中心扩展(单字符中心、双字符中心),更新最长子串的起始和结束位置。
8. 字符串转换整数 (atoi)
-
思路:正则匹配+状态机,处理空格、符号、数字,处理越界(用
long存储结果)。 -
关键点:正则表达式过滤非法字符,越界时返回边界值(
Integer.MAX_VALUE/MIN_VALUE)。
三、 哈希表 应用
1. 两数之和
-
思路:哈希表存储已遍历元素的值和下标,遍历数组时查找
target - nums[i]是否存在,存在则返回下标。 -
关键点:哈希表快速查找,处理重复元素时保证下标唯一。
36. 有效的数独
-
思路:用三个哈希表分别记录每行、每列、每个九宫格的数字出现次数,遍历棋盘验证唯一性。
-
关键点:九宫格索引计算(
(i/3)*3 + j/3),避免重复判断。
49. 字母异位词分组
-
思路:将字符串排序后作为键,原字符串作为值存入哈希表,同一键下的字符串为字母异位词。
-
关键点:排序后的字符串作为唯一键,利用
computeIfAbsent简化代码。
四、 双指针 技巧
27. 移动零
-
思路:双指针法,快指针遍历数组,慢指针记录非零元素位置,最后将慢指针后的元素置零。
-
关键点:快指针跳过零元素,慢指针复制非零元素。
11. 盛最多水的容器
-
思路:双指针从两端移动,每次移动较短板,计算当前面积并更新最大值。
-
关键点:贪心策略(移动短边可能找到更大面积),数学证明(短边限制面积上限)。
15. 三数之和
-
思路:排序后固定一数,双指针找另外两数,跳过重复元素避免重复解。
-
关键点:排序去重,双指针移动逻辑(根据和的大小调整指针)。
五、动态规划
70. 爬楼梯
-
思路:动态规划,状态转移方程
dp[i] = dp[i-1] + dp[i-2],初始化dp[1]=1, dp[2]=2,迭代计算。 -
关键点:空间优化(仅用两个变量存储前两项),避免数组空间浪费。
198. 打家劫舍
-
思路:动态规划,状态转移方程
dp[i] = max(dp[i-1], dp[i-2] + nums[i]),表示不抢或抢当前房屋的最大值。 -
关键点:滚动数组优化,避免存储整个dp数组。
300. 最长递增子序列
-
思路:动态规划,
dp[i]表示以nums[i]结尾的最长递增子序列长度,遍历前序元素更新dp[i]。 -
关键点:时间复杂度
O(n²),可优化为O(n log n)(贪心+二分)。
六、二叉树算法
94. 二叉树的 中序遍历
-
思路:递归实现中序遍历(左-根-右),迭代法用栈模拟递归过程。
-
关键点:递归终止条件(节点为空),迭代时栈存储待访问节点。
104. 二叉树的最大深度
-
思路:后序遍历(DFS),递归计算左右子树深度,当前节点深度为最大值+1。
-
关键点:递归返回值为子树深度,空节点深度为0。
114. 二叉树展开为 链表
-
思路:前序遍历展开,用指针记录前驱节点,将左子树插入到右子树位置。
-
关键点:递归展开左子树和右子树,处理指针连接顺序。
七、回溯算法
46. 全排列
-
思路:回溯法,用标记数组记录已使用元素,递归生成排列,回溯时撤销选择。
-
关键点:递归参数(路径、标记数组),终止条件(路径长度等于数组长度)。
78. 子集
-
思路:回溯法,从每个位置开始选择包含或不包含当前元素,避免重复组合(通过起始索引控制)。
-
关键点:收集所有路径(包括空集),起始索引避免重复选择。
90. 子集 II
-
思路:回溯法,排序数组后跳过重复元素,避免生成重复子集。
-
关键点:排序去重,
i > start时判断重复(nums[i] == nums[i-1])。
八、贪心算法
121. 买卖股票的最佳时机
-
思路:贪心遍历,记录当前最小值,计算当前价格与最小值的差值,更新最大利润。
-
关键点:一次遍历,时间复杂度
O(n)。
455. 分发饼干
-
思路:贪心排序,小饼干优先满足需求小的孩子,双指针匹配。
-
关键点:排序后双指针移动(饼干和孩子需求均升序)。
55. 跳跃游戏
-
思路:贪心维护当前最大覆盖范围,遍历数组判断是否可到达终点。
-
关键点:更新最大覆盖范围,若当前位置超过覆盖范围则返回false。
九、图论与BFS/DFS
200. 岛屿数量
-
思路:DFS/BFS,遍历每个单元格,遇到陆地则递归/迭代标记相邻陆地为已访问,统计岛屿数。
-
关键点:标记已访问单元格(改为'0'或使用visited数组),四个方向扩展(上下左右)。
127. 单词接龙
-
思路:BFS,构建单词图,每次变换一个字符,记录层次(最短变换次数)。
-
关键点:双向BFS优化,避免单向BFS的高时间复杂度。
十、其他算法(二分、栈、队列等)
33. 搜索旋转排序数组
-
思路:二分查找,先确定旋转点,再根据目标值与最后一个元素的大小关系,在相应有序区间查找。
-
关键点:判断当前中点属于左半区还是右半区,调整二分区间。
155. 最小栈
-
思路:栈+辅助栈,辅助栈记录当前栈中的最小值,保证push、pop、top、getMin均为
O(1)时间复杂度。 -
关键点:辅助栈与数据栈同步操作,存储历史最小值。