- 博客(74)
- 收藏
- 关注
原创 柱状图中最大的矩形
这可以用反证法证明:假如高度不在 heights 中,比如 4,那我们可以增加高度直到触及某根柱子的顶部,比如增加到 5,由于矩形底边长不变,高度增加,我们得到了面积更大的矩形,矛盾,所以面积最大矩形的高度一定是 heights 中的元素。• 栈顶是 1,height[1] = 1 < 2 → right[0] = 1。• 栈顶是 1,height[1] = 1 < 5 → left[2] = 1。• 栈顶是 1,height[1] = 1 < 2 → left[4] = 1。
2025-04-05 15:57:17
664
原创 LeetCode每日温度
给定一个数组 temperatures,其中 temperatures[i] 表示第 i 天的温度。• 继续检查栈中剩余的元素,直到栈为空或者栈顶元素的温度大于等于当前温度 temperatures[i]。栈顶索引对应的温度 temperatures[stack.top()],说明找到了栈顶索引位置的。• 计算两者的索引差 i - stack.top(),更新结果数组 ans,然后弹出栈顶元素。,也就是说,栈中的索引对应的 temperatures 值是递减的。,确保栈内的温度是递减的。
2025-04-02 16:25:40
408
原创 字符串解码
可以正确处理 "3[a2[c]]"、"2[abc]3[cd]ef" 等复杂情况!:存储 [ 之前已经解析的字符串,用于拼接被 [] 括起来的部分。我们来看字符串 s = "3[a2[c]]" 的完整解析过程。最终,res = "accaccacc",返回该字符串。遇到 ],弹出 2,重复 "c" 两次,并拼接 "a",表示 res = "acc" 需要重复 3 次。,表示 res = "c" 需要重复 2 次。遇到 ],弹出 3,重复 "acc" 三次。,与 "accaccacc" 拼接。
2025-03-31 15:49:54
412
原创 LeetCode最小栈
• 如果 ans.top() 等于 min_ans.top(),则 min_ans.pop(),同步删除最小值栈的顶端元素。• 如果 val 小于或等于 min_ans.top(),则 min_ans.push(val),维护最小值栈。(最小值栈):用于存储当前栈中的最小元素,使 getMin() 操作在 O(1) 时间内完成。(正常栈):存储所有入栈的元素,支持 push()、pop() 和 top() 操作。:O(1)(直接返回 min_ans.top()):O(1)(直接返回 ans.top())
2025-03-30 14:33:33
465
原创 寻找旋转排序数组中的最小值
我们用 nums = [4, 5, 6, 7, 1, 2, 3] 作为示例,• 如果 nums[left] < nums[right],说明。nums[left] > nums[right],进入二分查找。1. nums[mid] > nums[right],最小值在。2. nums[mid] ≤ nums[right],最小值在。:left == right,返回 nums[left]:只使用了 left 和 right 变量,O(1),直接返回 nums[left]。返回 nums[4] = 1。
2025-03-26 15:53:26
453
原创 搜索旋转排序数组
且 target < nums[mid],搜索左侧 right = mid - 1。• 若 nums[mid] >= nums[0],说明 mid。• 若 nums[mid] < nums[0],说明 mid。• nums[mid] == target 时,返回 mid。• nums[mid] >= nums[0],mid 在。• nums[mid] >= nums[0],mid 在。• nums[mid] < nums[0],mid 在。• nums[mid] < nums[0],mid 在。
2025-03-25 20:08:33
841
原创 在排序数组中查找元素的第一个和最后一个位置
可以在 O(log n) 时间复杂度内完成搜索,比 O(n) 的暴力搜索更快。,如果 target 不存在,返回 [-1, -1]。,nums[mid] = 7,小于 target,,如果找不到直接返回 [-1, -1]。,确保找到 target 的完整区间。:O(1)(只用了常数级别的变量)每次二分查找的时间复杂度是。
2025-03-24 14:28:57
207
原创 搜索二维矩阵
• 否则,返回 false(因为 target 只可能在当前行,不在其他行)。一定大于等于该行所有元素,且小于等于下一行的所有元素(如果有下一行)。当前行的最后一个元素,则 target 只能在后面的行,继续下一行。• 只使用了常数变量 left、right、mid,不需要额外的数组。通常 M 很大时,log M 远小于 N,所以二分查找优化明显。• left > right,找不到,返回 false。target,返回 true。target,返回 true。• 如果找到,返回 true。
2025-03-22 14:59:20
669
原创 最长公共子序列
• 若 text1[i-1] == text2[j-1],则 dp[i][j] = dp[i-1][j-1] + 1。1. 用 dp[i][j] 记录 text1[0:i] 和 text2[0:j] 的 LCS 长度。• 说明必须舍弃 text1[i-1] 或 text2[j-1] 之一,取较大的子问题结果。• 否则 dp[i][j] = max(dp[i-1][j], dp[i][j-1])。• dp[0][j] = 0(当 text1 为空时,LCS 长度为 0)。可以优化为 O(n) 使用。
2025-03-19 17:10:11
513
原创 最长回文子串
• 对于每个 i,调用 expandFromCenter 可能遍历整个字符串,因此最坏情况下 O(n²)。,以每个字符(或字符对)为中心向外扩展,找出最长回文子串。• 只使用了常数级额外变量,不需要 dp 数组。给定一个字符串 s,求 s 中最长的回文子串。(如 "aba",中心是 'b')(如 "abba",中心是 bb): "aba" 或 "bab"任何回文字符串,都有一个。
2025-03-18 13:55:34
309
原创 最小路径和
找到一条路径,使得路径上的数字之和最小,并返回该最小和。:路径和为 dp[i-1][j] + grid[i][j]:路径和为 dp[i][j-1] + grid[i][j]• 按行填充 grid,最终得出 dp[m-1][n-1]每个格子有一个非负整数值,表示走到该格子的消耗。我们在一个 m × n 的网格 grid 中,从。• 只使用一行 dp[j] 代替 grid,返回 grid[2][2] = 7,即。版(O(m × n) 空间)设 dp[i][j] 为。,路径上的数字和最小。版(O(n) 空间)
2025-03-18 12:55:42
302
原创 不同路径
• 递推关系:f[i][j] = f[i-1][j] + f[i][j-1]2. dp[j] = dp[j] + dp[j-1] 表示。• 计算 f 表,得 f[m-1][n-1] 作为答案。只能从左侧走过来,因此 f[0][j] = 1。只能从上方走过来,因此 f[i][0] = 1。1. 右 → 右 → 下 → 下。2. 右 → 下 → 右 → 下。3. 右 → 下 → 下 → 右。4. 下 → 右 → 右 → 下。5. 下 → 右 → 下 → 右。6. 下 → 下 → 右 → 右。
2025-03-16 14:47:36
266
原创 LeetCodehot 力扣热题100 最长有效括号
• 若栈不空:计算最长有效子串 i - stack.top()。如果有进一步的优化需求,比如 O(n) O(1) 解法,可以使用。• 维护一个初始值 -1 作为基准,以便计算子串长度。:栈存储索引,利用匹配索引计算最长有效子串长度。• 栈中存储的是索引,而不是字符本身。的数据结构,非常适合匹配括号问题。,即括号可以正确匹配的最长子序列。,如果你感兴趣,我可以介绍给你!:先存入 -1,作为基准。入栈 (存索引 0)入栈 (存索引 1)入栈 (存索引 3)入栈 (存索引 1)入栈 (存索引 3)
2025-03-15 15:43:21
305
原创 LeetCode 力扣热题100 分割等和子集
判断 dp[target] 是否为 true,其中 target = S / 2。✅ dp[9] = true,说明可以找到一个子集使得总和为 9,返回 true。• dp[j] = true 表示存在一个子集,使得该子集的和为 j。• dp[0] = true,表示和为 0 的子集是可行的(空集)表示可以用 {4} 得到和 4,可以用 {3, 4} 得到 7。2. 定义 dp[j]:表示能否找到一个子集,使得总和为 j。dp[9] = true,所以可以划分两个子集和相等。
2025-03-14 15:17:35
691
原创 黑马点评导入循环报错 LettuceConnectionFactory was destroyed and cannot be used anymore
这两个文件中的while循环注释掉就行。原因是redis还没有缓存。注意不要将方法名注释掉了。
2025-03-13 16:14:27
317
原创 乘积最大子数组
假设 nums = [2, 3, -2, 4],我们来看代码如何执行。• mini:当前子数组的最小乘积(因为负数可能反转最小值为最大值)1. 负数会改变乘积的大小,可能导致最大变最小,最小变最大。:O(1),只使用了 maxi、mini 和 ans 变量。给定一个整数数组 nums,要求找到一个。,使其乘积最大,并返回该最大乘积。• maxi:当前子数组的最大乘积。最终 ans 记录全局最大乘积。2. nums[i] 可能是。,每种情况的处理方式不同。:O(n),遍历数组一次。
2025-03-13 12:39:54
215
原创 LeetCode 力扣热题100 单词拆分
• j = 0, 1, 2 → s[0:3] = "lee"、s[1:3] = "ee"、s[2:3] = "e",都不在 wordDictSet,跳过。即,如果 s[0:j] 可以被拆分 (dp[j] == true),并且 s[j:i] 也在 wordDict 里,那么 dp[i] 也为 true。• j = 0 → s[0:4] = "leet",在 wordDictSet,且 dp[0] = true,所以 dp[4] = true。• dp[0] = true,表示空字符串可以被拆分。
2025-03-12 14:04:45
956
原创 LeetCodehot 力扣热题100 零钱兑换
• 硬币 1:可以兑换 1 元,dp[1] = min(dp[1], dp[1-1] + 1) = min(12, 0 + 1) = 1。• 硬币 1:dp[2] = min(dp[2], dp[2-1] + 1) = min(12, 1 + 1) = 2。• 硬币 1:dp[3] = min(dp[3], dp[3-1] + 1) = min(12, 1 + 1) = 2。• 硬币 2:dp[2] = min(dp[2], dp[2-2] + 1) = min(2, 0 + 1) = 1。
2025-03-11 12:43:16
410
原创 LeetCode 力扣热题100 完全平方数
• n = 12 → 12 = 4 + 4 + 4 → 最少 3 个完全平方数(3^2 不行,因为 9+3 不是完全平方数)。• dp[i] 默认初始化为 i,因为 i 最坏情况是 1 + 1 + ... + 1(全是 1 的平方)。最终 dp[12] = 3,即 12 = 4 + 4 + 4,需要 3 个完全平方数。• n = 13 → 13 = 4 + 9 → 最少 2 个完全平方数。• 如果 n 满足 n = 4^a × (8b + 7),返回 4。的完全平方数的个数,使它们的和等于 n。
2025-03-10 14:52:50
446
原创 LeetCodehot 力扣热图100 打家劫舍
第 i 间房子 → 获得 nums[i-1],并加上 dp[i-2](因为不能偷相邻房子)• dp[2] = max(nums[0], nums[1])(两间房子,偷金额较大的那间),给定一个整数数组 nums,其中 nums[i] 代表第 i 间房子里的现金。,只用两个变量存 dp[i-1] 和 dp[i-2],节省空间。• 只有一间房子 nums[0],最大金额就是 nums[0]。我们只需要 dp[i-1] 和 dp[i-2],可以用。: dp[i] 为前 i 个房子的最大可偷金额。
2025-03-10 14:23:36
577
原创 LeetCodehot 力扣热题100 划分字母区间
• 如果 i == end,说明当前片段结束,记录该片段长度 end - start + 1,并更新 start 为 end + 1。题目要求将字符串 s 划分为尽可能多的片段,每个片段中的字母不会出现在其他片段中,并返回这些片段的长度。• 先遍历字符串 s,用一个 last 数组(长度为 26,表示 a-z)存储。• end 表示当前片段的最远边界(即当前片段中所有字符的最远出现位置)。• 每遍历一个字符,都更新 end 为当前字符的最远出现位置。长度 8 - 0 + 1 = 9。a 最远出现位置 8。
2025-03-08 14:49:59
538
原创 LeetCodehot 力扣热题100 跳跃游戏2
i == end,执行 steps++,更新 end = maxReach = 4,终点已到达,跳出循环。i == end,执行 steps++,更新 end = maxReach = 2。我们需要从数组 nums 的起始位置 0 处,跳跃到数组的最后一个位置,并求。其中,nums[i] 表示在索引 i 处最多可以向前跳的步数。,表示当前层的跳跃边界。• 每次跳跃选择在当前范围内能跳得最远的点,保证最少步数。• 只用了几个整型变量,没有额外的数组或数据结构,,表示在当前层范围内,能跳到的最远索引。
2025-03-07 15:24:56
375
原创 LeetCodehot 力扣热题100 跳跃游戏
• 如果 i + nums[i] >= goal,说明从 i 可以直接或间接跳到 goal,那么。:从 0 出发,可以经过 [0]→[1]→[4] 到达终点,返回 true。:从 0 出发,最多只能跳到索引 3,无法到达索引 4,返回 false。,不断更新目标位置 goal,最终检查 goal == 0 是否成立。goal == 0,说明可以从起点跳到终点,返回 true。数组: [2] [3] [1] [1] [4]数组: [3] [2] [1] [0] [4]
2025-03-06 13:45:53
861
原创 LeetCodehot 力扣热题100 买卖股票的最佳时机
• 如果当前价格 price 比 cost 还低,就更新 cost。• 计算当前收益 price - cost,并更新 profit。• cost:记录历史最低买入价格,初始化为 INT_MAX。• profit 记录了整个遍历过程中能取得的最大收益。• prices[i] 表示第 i 天的股票价格。• profit:记录最大收益,初始化为 0。:每次都假设当前价格是最优解,更新最优答案。:$O(1)$,只用了常数额外空间。:$O(n)$,只遍历一次数组。• 代码简单高效,适用于。
2025-03-05 14:06:17
312
原创 LeetCodehot 力扣热题100 N 皇后
(不与之前的皇后冲突),则标记 col[c], diag1[r + c], diag2[r - c + n - 1],然后递归求解 r + 1 行。• 更新 diag2[0-0+3] = 1 (副对角线 r-c+n-1=3 被占用)• 更新 diag1[0+0] = 1 (主对角线 r+c=0 被占用)• 撤销 (3,3) → 继续尝试 r=3(无其他选项,回溯 r=2)• 若 r == n,说明所有行都放置了皇后,将解法加入 ans。我们从 r=0 开始,尝试在第一行 r=0 放置皇后。
2025-03-04 14:43:30
520
原创 LeetCodehot 力扣热题100 分割回文串
遍历 i = 0 到 n-1,寻找所有 s[0:j] 是回文的情况。遍历 i = 1 到 n-1,寻找所有 s[1:j] 是回文的情况。遍历 i = 2 到 n-1,寻找所有 s[2:j] 是回文的情况。遍历 i = 2 到 n-1,寻找所有 s[2:j] 是回文的情况。2 2 "b" ✅ 是回文 ["a", "a", "b"]2 2 "b" ✅ 是回文 ["aa", "b"]1 1 "a" ✅ 是回文 ["a", "a"]0 1 "aa" ✅ 是回文 ["aa"]0 0 "a" ✅ 是回文 ["a"]
2025-03-03 15:17:43
657
原创 LeetCodehot 力扣热题100 组合总和
遍历整个 board,每个字符最多进行 4 次递归,时间复杂度 O(m * n * 4^L),其中 m, n 为网格大小,L 为 word 长度。遍历过程中,找到 word[0] = 'A' 的位置 (0,0),开始 DFS。1 (0,0) 'A' → (0,1) 匹配,向右搜索。2 (0,1) 'B' → (0,2) 匹配,向右搜索。3 (0,2) 'C' ↓ (1,2) 匹配,向下搜索。4 (1,2) 'C' ↓ (2,2) 匹配,向下搜索。5 (2,2) 'E' ← (2,1) 匹配,向左搜索。
2025-03-02 16:11:41
743
原创 LeetCodehot 力扣热图100 括号生成
│ │ └─ 添加')' → "(()" → ... → "(()())", "(())()"│ ├─ 添加'(' → "()(" → ... → "()(())", "()()()"│ │ │ └─ 添加')' → "((()" → ... → "((()))"递归调用 backtrack(3,2,3,"((())")递归调用 backtrack(3,2,3,"(()()")递归调用 backtrack(3,2,3,"(())(")
2025-03-01 15:30:07
532
原创 LeetCodehot 力扣热题100 组合总和
• 首先对 candidates 进行排序,得到 [2, 3, 6, 7]。• 调用 combination(res, candidates, 0, 0, 7),开始从候选数值的第一个数字开始递归,res 是当前的组合,sum 是当前组合的和,n 是当前递归的索引,target 是目标和。• 递归调用:combination([2, 2, 2], [2, 3, 6, 7], 0, 6, 7)。• 递归调用:combination([2, 2], [2, 3, 6, 7], 0, 4, 7)。
2025-02-28 15:21:38
953
原创 LeetCodehot 力扣热题100 电话号码的字母组合
• 生成字母组合 "cd", "ce", "cf",将它们添加到结果中:ans = ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]。• 类似地,生成字母组合 "bd", "be", "bf",将它们依次添加到结果中:ans = ["ad", "ae", "af", "bd", "be", "bf"]。• 生成字母组合 "af",将其添加到结果中:ans = ["ad", "ae", "af"]。• 回溯:移除 ‘e’,继续尝试 ‘f’。
2025-02-27 13:29:30
604
原创 LeetCodehot 力扣热题100 子集
• 将 nums[2](即 3)加入路径 path,现在 path = [1, 2, 3]。• 将 nums[1](即 2)加入路径 path,现在 path = [1, 2]。• 将 nums[2](即 3)加入路径 path,现在 path = [1, 3]。• 将 nums[2](即 3)加入路径 path,现在 path = [2, 3]。• 将 nums[1](即 2)加入路径 path,现在 path = [2]。• 递归调用 back([1, 2, 3], [1, 2, 3], 3)。
2025-02-26 14:54:28
740
原创 LeetCodehot 力扣热题100 全排列
• 当前节点的起始值是 nums = [1, 2, 3],n = 2,遍历 i = 2 到 i = 2(只剩下一个位置)。• 当前节点的起始值是 nums = [1, 3, 2],n = 2,遍历 i = 2 到 i = 2(只剩下一个位置)。• 当前节点的起始值是 nums = [2, 1, 3],n = 2,遍历 i = 2 到 i = 2(只剩下一个位置)。• 当前节点的起始值是 nums = [2, 3, 1],n = 2,遍历 i = 2 到 i = 2(只剩下一个位置)。
2025-02-25 13:22:50
746
原创 LeetCodehot 力扣热题100 实现 Trie (前缀树)
• 最后,我们到达单词 “apple” 的结尾节点,并且 isEnd = true,说明单词 “apple” 存在,返回 true。• 到这里,“apple” 的所有字符都插入完毕,我们将最后一个节点的 isEnd 标记为 true,表示这是一个完整的单词。• 最后,我们到达 “app” 的结尾节点,并且 isEnd = true,说明单词 “app” 存在,返回 true。:每次插入一个单词时,我们会遍历该单词的每个字符,并在 Trie 树中逐步创建新的节点或沿用已有的节点。
2025-02-24 15:21:18
1041
原创 LeetCodehot 力扣热题100 课程表
好的,下面我会为你提供更加详细的运行步骤,并结合一个具体的示例进行演示,帮助你理解如何通过图的 DFS(深度优先搜索)来检测是否能完成所有课程。:每个课程和每条依赖边只会被访问一次,因此 DFS 的时间复杂度是 O(V + E),其中 V 是课程数,E 是依赖关系数。在 dfs 函数中,我们递归访问课程的前置课程。课程的依赖关系被表示为一个有向图,每个节点代表一门课程,每条边表示一门课程的前置课程。所有课程的状态都为 2,表示它们都已完成访问,没有发现环,因此可以完成所有课程,返回 true。
2025-02-23 15:43:28
549
原创 LeetCodehot 力扣热题100 腐烂的橘子
问题的目标是找出腐烂橙子传染所有新鲜橙子的最短时间,或者在无法感染所有新鲜橙子的情况下返回 -1。• 使用 BFS 模拟腐烂过程,每轮遍历腐烂橙子的 4 个方向,感染相邻的新鲜橙子,直到没有新鲜橙子可以感染。• 使用一个队列来存储腐烂橙子的坐标,最多存储所有腐烂橙子的位置,空间复杂度是。• 初始状态是所有腐烂的橙子进入队列,每次 BFS 都扩展相邻的新鲜橙子。• 初始化:计算网格的行列数,统计新鲜橙子的数量并找到腐烂橙子的初始位置。1. 初始时,腐烂橙子的位置为 (0,0),新鲜橙子数量为 4。
2025-02-22 14:21:00
915
原创 LeetCode100 力扣热题100 岛屿数量
• grid[0][0] = '1',启动 DFS,ans++,ans = 1,然后将岛屿位置 '1' 转换为 '0'。• grid[2][2] = '1',启动 DFS,ans++,ans = 2,然后将岛屿位置 '1' 转换为 '0'。• grid[3][3] = '1',启动 DFS,ans++,ans = 3,然后将岛屿位置 '1' 转换为 '0'。:从当前 '1' 开始,DFS 会向上下左右四个方向扩展,找到所有连接的 '1',并将它们标记为 '0',表示已访问。
2025-02-21 14:37:02
587
原创 LeetCodehot 力扣热题100
问题的目标是:在一个二叉树中找到一条路径,使得路径上的节点值的和最大。• dfs(root->left) 和 dfs(root->right) 分别递归地计算左子树和右子树的最大路径和。• left = 7,right = 3,节点 1 的路径和是 1 + 7 + 3 = 11,max_sum 不变。• root->val + max(left, right) 表示包括当前节点和其较大子树路径和的最大路径和。:每个节点返回的路径和代表它向上回溯的贡献,它是当前节点值与左、右子树最大路径和中的较大者之和。
2025-02-20 14:08:07
817
原创 LeetCodehot 力扣热题100 二叉树的最近公共祖先
其核心思想是通过后序遍历自底向上搜索,一旦在当前节点的左子树和右子树中分别找到 `p` 或 `q`,则该当前节点即为它们的LCA。通过这样的递归过程,函数最终会返回正确的最近公共祖先。例如,如果我们传入不存在的节点 p = 10 和 q = 11,递归到树的叶子节点时会返回 nullptr。由于左子树和右子树的返回值都不为空,这意味着节点 5 和节点 1 分别位于左右子树,因此当前节点 3 是它们的最近公共祖先。我们传入 root = 3,p = 5,q = 1,目标是找到这两个节点的最近公共祖先。
2025-02-19 15:21:46
854
原创 LeetCodehot 力扣热题100 路径总和 III
通过前缀和的巧妙使用,这个算法能高效地解决路径总和的问题,避免了暴力的 O(N^2) 复杂度,并且使用回溯避免了重复计算。
2025-02-16 12:02:28
794
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人