link:https://leetcode.cn/studyplan/top-interview-150/
| 日期 | 题号 | 备注 |
| 2025.5.22 | 88. 合并两个有序数组 - 力扣(LeetCode) | 通过双指针法从后向前合并来解决,避免覆盖nums1中的元素 |
| 2025.5.23 | 27. 移除元素 - 力扣(LeetCode) | 用快慢指针 slow用来标识有效元素的下标 fast用来遍历整个数组 slow和fast都从下标0开始 如果nums[fast] != val, 将fast的值复制到slow的位置,然后移动slow |
| 2025.5.24 | 26. 删除有序数组中的重复项 - 力扣(LeetCode) | 用快慢指针 fast用来遍历数组 slow标识新元素的下标 需要时刻考虑fast指针是否越界的问题 |
| 2025.5.25 | 80. 删除有序数组中的重复项 II - 力扣(LeetCode) | 用快慢指针 长度小于2,直接返回,slow和fast都从下标2开始 slow指针表示修改后数组的下标,fast遍历整个数组 比较 nums[fast] == nums[slow-2]:true, continue; false,给slow赋值 |
| 2025.5.26 | 169. 多数元素 - 力扣(LeetCode) | 最简单的:摩尔投票法 初始化候选人和计数器 遍历数组元素,相同元素则计数器+1,不同则-1 当计数器归零时更换候选元素 最终候选人即为所求 错误点:在count变为0时,将候选人设置为当前元素,并将count重置为1 |
| 2025.5.27 | 189. 轮转数组 - 力扣(LeetCode) | 反转直接写for循环 需要将k取模,来处理k大于数组长度的情况 |
| 2025.5.28 | 121. 买卖股票的最佳时机 - 力扣(LeetCode) | 直接跳过,自己做出来的 类似动态规划的思想: minPrice 记录当前最低的股票价格 maxProfit 记录已知的最大利润 |
| 2025.5.29 | 122. 买卖股票的最佳时机 II - 力扣(LeetCode) | 用贪心算法,捕捉所有上升趋势的机会,并且就在第一天买,第二天卖 |
| 135. 分发糖果 - 力扣(LeetCode) | 贪心算法,维护两个数组 从左到右:确保右边孩子的糖果比左边孩子多 从右到左:确保左边孩子的糖果比右边孩子多 没考虑到的地方:当前评分不大于前一个时,应该将糖果数设为1,而不是保持前一个的值 两个数组中取最大值 | |
| 2025.5.30 | 55. 跳跃游戏 - 力扣(LeetCode) | 动态规划(自己想到的):
贪心算法:
|
| 2025.6.2 | 45. 跳跃游戏 II - 力扣(LeetCode) | (没想到) 用贪心算法:每一步都尽量跳得最远,这样才能保证跳跃次数最少。 end = 0, farthest = 0, jump = 0。 end: 当前这一跳的最远位置;farthest:当前跳跃范围内,通过每一步能到达的最远位置。 每当你走到end时(即i==end),说明你需要跳一次,此时jumps++,并把end更新为farthest。 只要能覆盖到最后一个元素,就可以结束了。 |
| 2025.6.3 | 274. H 指数 - 力扣(LeetCode) | (想到了暴力解法) 从数组里面的最大值开始遍历 value 找到符合 citations[i] >= value 的个数 count 如果count == value, 返回value 不然继续 优化: 排序 + 一次遍历 先把数组排序,第i篇论文的引用数是citation[n-i] 从前向后找,找到第一个 citations[i] >= n-i,说明有 n-i 篇论文引用不少于 n-i 次 |
| 2025.6.4 | 380. O(1) 时间插入、删除和获取随机元素 - 力扣(LeetCode) | 用空间换时间
初始化map的方法:make(map[int]int) 判断key是否存在的方法: index, exists := this.Mapping[val] 删除key的方法: delete(this.Mapping, val) 设置随机种子:rand.Seed(time.Now().UnixNano()), keys[rand.Intn(len(keys))] |
| 2025.6.5 | 238. 除自身以外数组的乘积 - 力扣(LeetCode) | 自己想到的:
|
| 42. 接雨水 - 力扣(LeetCode) | 动态规划:两个数组记录左右两边的最大值 当前网格储水量 = min(leftMax[i], rightMax[i]) - 当前高度 | |
| 2025.6.6 | 13. 罗马数字转整数 - 力扣(LeetCode) | 从左到右累加
|
| 2025.6.9 | 134. 加油站 - 力扣(LeetCode) | 想到了暴力解法, 拼接数组的逻辑:
贪心算法:
|
| 2025.6.10 | 12. 整数转罗马数字 - 力扣(LeetCode) | 贪心算法:
|
| 2025.6.11 | 58. 最后一个单词的长度 - 力扣(LeetCode) | 自己想到的: 先跳过末尾的所有空格,再直接遍历找出末尾最后一个单词的长度 |
| 2025.6.12 | 14. 最长公共前缀 - 力扣(LeetCode) | 自己想到的:逐个比较每个字符的最长公共前缀 |
| 151. 反转字符串中的单词 - 力扣(LeetCode) | 自己想到的:
| |
| 2025.6.16 | 28. 找出字符串中第一个匹配项的下标 - 力扣(LeetCode) | 用双指针 slow: 用来标志第slow个字符被检查过是否符合了,取值 0 到 两个长度之差 比较的时候应该是slow+j和j的下标进行比较 |
| 2025.6.17 | 125. 验证回文串 - 力扣(LeetCode) | 先都转换成小写,在保留所有的小写字母,最后双指针判断是否是回文串 // 编译超时改进拼接字符串: |
| 2025.6.18 | 392. 判断子序列 - 力扣(LeetCode) | 自己想到的: 双指针 |
| 167. 两数之和 II - 输入有序数组 - 力扣(LeetCode) | 想到了暴力解法,也可以用双指针 i=0,j = len(numbers) - 1: 两数之和<target,i++; 两数之和>target,j--; | |
| 2025.6.19 | 11. 盛最多水的容器 - 力扣(LeetCode) | 想到了贪心算法, 最大水量 = width * min(height) 没想到:从两边开始向中间挪最短的边,不断更新最大水量 |
| 2025.6.20 | 15. 三数之和 - 力扣(LeetCode) | 想到:先排序,在固定一个值后用双指针 没想到的:需要跳过重复的值,跳过后记得更新双指针 |
| 2025.6.23 | 209. 长度最小的子数组 - 力扣(LeetCode) | 没想到:可以用滑动窗口: left, right := 0, 0 向右移动right,直到 sum >= target, 设置一个变量记录result 移动左窗口来缩小滑动窗口; 继续移动right,重复上面的步骤 |
| 2025.6.27 | 3. 无重复字符的最长子串 - 力扣(LeetCode) | 想到思路,实现卡了好几天: 也用滑动窗口,left,right 用一个map[byte]int来维护,int可以下标的值 left,right双指针:
|
| 2025.6.30 | 36. 有效的数独 - 力扣(LeetCode) | 自己没有想到的: 用3个二维数组是否存在的状态
byte 转int:intVal, _ := strconv.Atoi(string(val)) 初始化数组: var rows [9][9]bool |
| 2025.7.1 | 383. 赎金信 - 力扣(LeetCode) | 自己想到的 直接用一个数组维护magazine; index = char - 'a', 遍历ransomNote,存在的话val-1, 不存在return false |
| 2025.7.2 | 54. 螺旋矩阵 - 力扣(LeetCode) | 没想到,边界控制法 从左到右 -> 从上到下 -> 从右到左 -> 从下到上 更新位置的时候应该在if条件里面 从右到左应该检查上下边界 从下到上应该检查左右边界 |
| 2025.7.3 | 48. 旋转图像 - 力扣(LeetCode) | matrix[i][j] 和 matrix[n-1-i][n-1-j]互换顺序 上下的行互换顺序 沿着对角线互换顺序没想到: |
| 2025.7.4 | 73. 矩阵置零 - 力扣(LeetCode) | 自己想到的: 先遍历一遍数组把需要置为0的行和列都存下来,然后直接赋0 |
| 2025.7.7 | 205. 同构字符串 - 力扣(LeetCode) | 没想到,维护两个mapping s2t 和 t2s 把t和s的值相互映射,确认是否有重复的映射关系 |
| 2025.7.8 | 290. 单词规律 - 力扣(LeetCode) | 自己想到的,还是用两个数组维护映射关系 p2s := make(map[byte]string) s2p := make(map[string]byte) p2s[char] != "" s2p[str] > 0 |
| 2025.7.10 | 242. 有效的字母异位词 - 力扣(LeetCode) | 自己想到的,注意遍历string数组的方式: mapping := make(map[rune]int) for _, c := range s {...} |
| 2025.7.14 | 49. 字母异位词分组 - 力扣(LeetCode) | 自己没想到 用计数法,记下26个字母每个字母出现的次数,然后拼接成一个string 相同key的就是字母异位 |
| 2025.7.15 | 1. 两数之和 - 力扣(LeetCode) | 自己想到的 用一个map[int]int数组保存,key是当前值,value是下标 |
| 2025.7.17 | 202. 快乐数 - 力扣(LeetCode) | 思路没想到,代码自己写的 使用一个map集合来判断是否出现了重复的数字 出现了就不是快乐数字,没出现就是 |
| 2025.7.18 | 219. 存在重复元素 II - 力扣(LeetCode) | 用一个map[int]int来存储:key是nums[i],value 是i 如果map[nums[i]]已经存在: if abs(i - j) <= k, 成立就return true else map[nums[i]] = 新的i。 如果map[nums[i]]不存在, map[nums[i]] = i 继续循环,直到最后一个值还不成立,return false math.Abs(float64(index - i)) <= float64(k) |
| 2025.8.4 | 128. 最长连续序列 - 力扣(LeetCode) | 没想到: 把每个值都先存到一个map里,key是数组里出现的值,value是1 遍历数组,只从起始值开始遍历; 起始值的定义:value - 1 不再map里,在的话就不需要遍历 再用visited的map记录某个值是否被访问过 |
| 2025.8.5 | 228. 汇总区间 - 力扣(LeetCode) | 自己想到的: 循环遍历nums数组 判断 nums[i+1] == nums[i]+1: 不等于直接append 等于的话继续向后循环 |
| 2025.8.6 | 56. 合并区间 - 力扣(LeetCode) | 有思路,没写出来: 先按照集合的第一个数字进行排序: sort.Slice(result, func(i, j int) bool { return result[i][0] < result[j][0] }) 贪心合并:不需要新建临时数组 |
| 2025.8.8 | 57. 插入区间 - 力扣(LeetCode) | 没思路 1. 处理完全在新区间左侧的区间 2. 处理重叠区间 2.1 有重叠,开始合并 2.2 继续检查后续区间是否还与合并后的区间重叠 2.3 新区间不与任何现有区间重叠,直接添加 3. 处理完全在新区间右侧的区间 |
| 2025.8.11 | 452. 用最少数量的箭引爆气球 - 力扣(LeetCode) | 没思路: 1. 按右端点排序所有气球 初始化箭数为1,第一支箭位置为第一个气球的右端点 2. 遍历后续气球: 如果当前气球左端点 > 当前箭位置,需要新箭 新箭位置设为当前气球的右端点 3. 返回总箭数 |
| 2025.8.13 | 20. 有效的括号 - 力扣(LeetCode) | 使用栈,goland应该是不支持栈的,使用切片模拟 // 入栈(push) stack = append(stack, 1) // [1] stack = append(stack, 2) // [1, 2] // 查看栈顶元素(peek) if len(stack) > 0 { top := stack[len(stack)-1] fmt.Println("栈顶元素:", top) // 输出: 栈顶元素: 2 } // 出栈(pop) if len(stack) > 0 { stack = stack[:len(stack)-1] // [1] } 遇到左边的括号( { [, push到栈里 遇到右边的括号,pop出来 |
| 2025.8.14 | 71. 简化路径 - 力扣(LeetCode) | 自己做出来的(加粗问的ai) 按照/ 或者 //分组: 先按照/分割,然后过滤掉空的值 把每个值放到切片里 如果是., 直接忽略 如果是..,弹出第一个元素, 没得弹出的时候continue |
| 2025.8.22 | 155. 最小栈 - 力扣(LeetCode) | 用切片模拟 自己写出来的 |
| 2025.8.25 | 150. 逆波兰表达式求值 - 力扣(LeetCode) | 用栈解决。 遇到数字就放入栈,遇到计算符号就弹出两个数字 错误的点: 1. 把当前计算出的结果再压回栈中 2. 判断是不是数字 strconv.Atoi。strconv.Atoi 的 err 就能判断是不是运算符 |
| 链表 | ||
| 2025.8.27 | 141. 环形链表 - 力扣(LeetCode) | 使用快慢指针:快的一次走两步,慢的一次走一步,每次走的时候都要判断能不能走 如果两个指针相遇了 -〉 有环 如果不能走,到尽头了 -〉 没环 |
| 2025.8.29 | 2. 两数相加 - 力扣(LeetCode) | 新建一个链表来存储结果 设置一个进位符,每当相加的结果超过10的时候,进位符 = 1; 否则0 |
| 2025.9.1 | 合并两个有序链表 | 直接做出来的 |
| 2025.9.4 | 138. 随机链表的复制 - 力扣(LeetCode) | 想错思路了,正确做法: 1. 遍历原链表,复制每个节点,并建立原节点到新节点的映射 2. 再次遍历原链表,复制`Next`和`Random`指针 |
| 2025.9.5 | 92. 反转链表 II - 力扣(LeetCode) | 自己没有想到: 定位区间 -> 反转区间 -> 连接区间 找left-1的节点 反转逻辑: cur := pre.Next for i := 0; i < right - left; i++{ temp := cur.Next cur.Next = temp.Next temp.Next = pre.Next pre.Next = temp } 返回新链表头 |
| 2025.9.9 | https://leetcode.cn/problems/remove-nth-node-from-end-of-list/?envType=study-plan-v2&envId=top-interview-150 | 长度5,倒数第2个节点,需要走到第(5-2)个节点, 走(5-2-1)步 如果删除的是第一个节点,需要特殊处理 |
| 2025.9.10 | https://leetcode.cn/problems/remove-duplicates-from-sorted-list-ii/submissions/661241271/?envType=study-plan-v2&envId=top-interview-150 | 自己想到的解法只能删除相邻重复节点中的一个 设置dummy节点 如果发现重复值,记录重复的值,删除所有值为val的节点 如果没有重复,移动prev指针 |
| 2025.9.25 | https://leetcode.cn/problems/rotate-list/?envType=study-plan-v2&envId=top-interview-150 | 1. 把首位节点相连 2. ListNode的长度是length 3. k = k % length; 4. 首节点移动(length - k -1),cur 断开 没想到的: 1. k == 0 的时候,不要继续 |
| 2025.9.28 | https://leetcode.cn/problems/partition-list/submissions/666774439/?envType=study-plan-v2&envId=top-interview-150 | 自己想到了用两个切片存less & more,然后按顺序重建链表 优化:两个虚拟头 less 和 greater,一次遍历把原链表的节点“摘下”接到对应链表尾部 |
7万+

被折叠的 条评论
为什么被折叠?



