自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(40)
  • 收藏
  • 关注

原创 算法训练营Day46 - 单调栈part01

给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。

2026-03-29 02:35:06 347

原创 算法训练营Day45 - 动态规划part13

如果这矩阵是从上到下,从左到右遍历,那么会用到没有计算过的dp[i + 1][j - 1],也就是根据不确定是不是回文的区间[i+1,j-1],来判断了[i,j]是不是回文,那结果一定是不对的。如果s[i]与s[j]不相同,说明s[i]和s[j]的同时加入 并不能增加[i,j]区间回文子序列的长度,那么分别加入s[i]、s[j]看看哪一个可以组成最长的回文子序列。那么dp[i][j]一定是取最大的,即:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);

2026-03-26 13:06:36 340

原创 算法训练营Day44 - 动态规划part12

那最后当然是取最小值,所以当word1[i - 1] 与 word2[j - 1]不相同的时候,递推公式:dp[i][j] = min({dp[i - 1][j - 1] + 2, dp[i - 1][j] + 1, dp[i][j - 1] + 1});因为 dp[i][j - 1] + 1 = dp[i - 1][j - 1] + 2,所以递推公式可简化为:dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1);

2026-03-26 11:53:54 361

原创 算法训练营Day42 - 动态规划part11

t[j - 1]),此时相当于t要删除元素,t如果把当前元素t[j - 1]删除,那么dp[i][j] 的数值就是 看s[i - 1]与 t[j - 2]的比较结果了,即:dp[i][j] = dp[i][j - 1];第三步 dp数组如何初始化:从递推公式可以看出dp[i][j]都是依赖于dp[i - 1][j - 1] 和 dp[i][j - 1],所以dp[0][0]和dp[i][0]是一定要初始化的。这里大家已经可以发现,在定义dp[i][j]含义的时候为什么要。

2026-03-25 10:53:06 329

原创 算法训练营Day41 - 动态规划part10

连续递增的子序列 可以由两个下标 l 和 r(l < r)确定,如果对于每个 l <= i < r,都有 nums[i] < nums[i + 1] ,那么子序列 [nums[l], nums[l + 1], ..., nums[r - 1], nums[r]] 就是连续递增子序列。即当A[i - 1] 和B[j - 1]相等的时候,dp[i][j] = dp[i - 1][j - 1] + 1;根据dp[i][j]的定义,dp[i][j]的状态只能由dp[i - 1][j - 1]推导出来。

2026-03-22 14:34:49 344

原创 算法训练营Day40 - 动态规划part09

所以:dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i] - fee);选最大的,所以 dp[i][1] = max(dp[i - 1][0] - prices[i], dp[i - 1][1]);所以:dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);dp[i][0] 表示第i天持有股票所得最多现金。使用二维数组 dp[i][j] :第i天的状态为j,所剩下的最大现金是dp[i][j]

2026-03-21 10:50:42 316

原创 算法训练营 Day39 - 动态规划part08

状态含义dp[i][0]没有任何操作dp[i][1]第一次持有股票dp[i][2]第一次卖出后dp[i][3]第二次持有股票dp[i][4]第二次卖出后状态只能单向推进,不能倒退。

2026-03-18 11:11:15 292

原创 算法训练营 Day38 - 动态规划part07

dp[i] 依赖于 dp[i-1] 和 dp[i-2]。拆分为两个线性问题。每个节点返回[不偷, 偷]两个状态。

2026-03-16 16:01:50 368

原创 算法训练营 Day37 - 动态规划part06

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。你可以认为每种硬币的数量是无限的。示例 1:示例 2:示例 3:示例 4:示例 5:提示:如果求组合数就是外层for循环遍历物品,内层for遍历背包。如果求排列数就是外层for遍历背包,内层for循环遍历物品。每种硬币的数量是无限的,可以看出是典型的完全背包问题。dp[j]:凑足总额为j所需钱币的最少个数为dp[j]凑足总额为j - coins[

2026-03-16 13:02:04 362

原创 算法训练营 Day36 - 动态规划part05

完全背包有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i]。,求解将哪些物品装入背包里物品价值总和最大。。例子:问背包能背的物品最大价值是多少?。第二步 确定递推公式::背包容量为j,里面不放物品i的最大价值是dp[i - 1][j]。

2026-03-01 14:14:51 1001

原创 算法训练营 Day35 - 动态规划part04

1049. 最后一块石头的重量 II有一堆石头,每块石头的重量都是正整数。每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:如果 x == y,那么两块石头都会被完全粉碎;如果 x!= y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。最后,最多只会剩下一块石头。返回此石头最小的可能重量。如果没有石头剩下,就返回 0。。石头的重量是 stones[i],石头的价值也是 stones[i]。

2026-02-27 13:15:34 945

原创 算法训练营 Day34 - 动态规划part03

01背包问题 二维有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i]。,求解将哪些物品装入背包里物品价值总和最大。第一步:d。第二步:这里我们dp[1][4]的状态来举例:如果不放物品1, 那么背包的价值应该是 dp[0][4] 即 容量为4的背包,只放物品0的情况。推导方向如图:如果放物品1,,目前容量是4,物品1 的容量(就是物品1的重量)为3,此时背包剩下容量为1。

2026-02-26 18:38:22 666

原创 算法训练营 Day33 - 动态规划part02

62.不同路径一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。问总共有多少条不同的路径?解释: 从左上角开始,总共有 3 条路径可以到达右下角。dp[i][j] :表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路径。想要求dp[i][j],只能有两个方向来推导出来,即dp[i - 1][j] 和 dp[i][j - 1]。

2026-02-25 13:51:10 1540

原创 算法训练营 Day32 - 动态规划 Part01

一定是选最小的,所以dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);首先是dp[i - 1],上i-1层楼梯,有dp[i - 1]种方法,那么再一步跳一个台阶不就是dp[i]了么。dp[i - 1] 跳到 dp[i] 需要花费 dp[i - 1] + cost[i - 1]。dp[i - 2] 跳到 dp[i] 需要花费 dp[i - 2] + cost[i - 2]。第一步:dp[i]的定义为:第i个数的斐波那契数值是dp[i]

2026-02-19 09:20:18 896

原创 算法训练营 Day31 - 贪心算法 Part05

状态 0:无覆盖 (Uncovered)—— 这个节点需要被照看,但目前没被覆盖。状态 1:有摄像头 (Camera)—— 这个节点安装了摄像头。状态 2:有覆盖 (Covered)—— 这个节点虽然没装摄像头,但被它的子节点覆盖了。贪心策略:从下往上,跳过叶子,在叶子的父节点放摄像头,每隔两层放一个。时间复杂度:O(n)。每个节点只被访问一次。空间复杂度:O(h)。$h$ 是树的高度,主要开销是递归调用的栈空间。

2026-02-18 11:29:18 1152

原创 算法训练营 Day30 - 贪心算法part04

在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足 xstart ≤ x ≤ xend,则该气球会被引爆。对于每个气球,提供的输入是水平方向上,气球直径的开始和结束坐标。给你一个数组 points ,其中 points [i] = [xstart,xend] ,返回引爆所有气球所必须射出的最小弓箭数。区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。763.划分字母区间。

2026-02-15 05:34:10 917

原创 算法训练营 Day29 - 贪心算法part03

134. 加油站134. 加油站在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。示例 2: 输入:输出: -1解释: 你不能从 0 号或 1 号加油站出发,因为没有足够的汽油可以让你行驶到下一个加油站。我们从 2 号加油站出发,可以获得 4 升汽油。

2026-02-15 02:15:48 632

原创 算法训练营 Day28 - 贪心算法part02

局部最优推出全局最优,找不出反例,试试贪心!

2026-02-13 11:28:56 702

原创 算法训练营 Day27 - 贪心算法part01

例如, [1,7,4,9,2,5] 是一个摆动序列,因为差值 (6,-3,5,-7,3) 是正负交替出现的。相反, [1,4,7,2,5] 和 [1,7,4,5,5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。所以只要当前的“累积和”变成了负数,它对未来就没有任何贡献了,直接丢弃,从现在重新开始算。(最大的饼干给最贪心的孩子,或者最小的饼干给最小胃口的孩子,不要浪费)。如果是单调递增(1, 2, 3, 4),中间的数都没用,只要两头。

2026-02-12 09:18:45 952

原创 算法训练营 Day25 - 回溯算法part04

491.递增子序列给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2。这题根据模板解决,continue的判定条件很重要。删除了依赖排序的,改用了来记录当前层级使用过的数字。46.全排列给定一个 没有重复 数字的序列,返回其所有可能的全排列。之前的题目(组合、子集)讲究的是“”,所以需要startidx。而全排列讲究的是“”,所以startidx,每次都要从头遍历。

2026-02-11 08:33:18 730

原创 算法训练营 Day 24 - part03

因为 IP 地址被 3 个点分成 4 部分。

2026-02-10 10:54:36 768

原创 算法训练营 Day23 - 回溯算法part02

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。这行代码的意思是:如果在当前这一层中,我已经用过了一个相同的数字,那么后面再遇到它就跳过,这样能彻底杜绝结果集中的重复组合。,这确保了在进入下一层递归时,程序会从当前数字的下一个位置开始搜寻,满足了题目‘每个数字只能使用一次’的要求。循环中,如果前一个数字和当前数字相同且前一个已经处理过,就要跳过,否则会出现重复组合。这道题可以看作是一个“组合问题”的变体。

2026-02-09 11:57:55 898

原创 算法训练营 Day22 - 回溯算法part01

回溯法一般是在集合中递归搜索,集合的大小构成了树的宽度,递归的深度构成的树的深度。如图:注意图中,我特意举例集合大小和孩子的数量是相等的!for循环就是遍历集合区间,可以理解一个节点有多少个孩子,这个for循环就执行多少次。backtracking这里自己调用自己,实现递归。大家可以从图中看出,这样就把这棵树全遍历完了,一般来说,搜索叶子节点就是找的其中一个结果了。77. 组合给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。

2026-02-08 10:12:02 857

原创 算法训练营 day 21 - 二叉树part08

通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L)。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。节点的左子树仅包含键 小于 节点键的节点。节点的右子树仅包含键 大于 节点键的节点。本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

2026-02-07 15:51:14 200

原创 算法训练营 day 20 - 二叉树part07

235. 二叉搜索树的最近公共祖先235. 二叉搜索树的最近公共祖先给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]

2026-02-06 16:29:47 1021

原创 算法训练营 Day 18 - 二叉树 part06

首先,我们要明确这个函数究竟在干什么。“嘿,root,你去你的子树里找 p 和 q。如果你就是 p 或 q,把你自已交上来。如果你的左子树或者右子树里发现了 LCA,把那个 LCA 交上来。如果你的子树里只发现了 p,把 p 交上来(q 同理)。如果你啥都没找到,交个 None 上来。这个返回值的多重含义是理解难点。这道题的难点在于相信递归函数的定义。不要试图用人脑去模拟整个递归栈(会晕),而是要抓住当前节点root需要做什么如果我就是目标,返回我。看看左右孩子给了我什么。

2026-02-02 07:01:32 889

原创 算法训练营 Day 17 - 二叉树 part05

654.最大二叉树给定一个不含重复元素的整数数组。通过给定的数组构建最大二叉树,并且输出这个树的根节点。示例 :提示:给定的数组的大小在 [1, 1000] 之间。使用前序可以简单解决:中左右先用max找root,再记录index。再设置node,使用切片先走左再走右。617.合并二叉树给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。你需要将他们合并为一个新的二叉树。

2026-01-31 10:29:40 439

原创 算法训练营 Day16 - 二叉树 part04

513 找树左下角的值给定一个二叉树,在树的最后一行找到最左边的值。

2026-01-30 08:42:45 358

原创 算法训练营 Day15 - 二叉树 part03

110.平衡二叉树 (优先掌握递归)给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。示例 1:给定二叉树 [3,9,20,null,null,15,7]返回 true。示例 2:给定二叉树 [1,2,2,3,3,null,null,4,4]返回 false。我们不需要返回。我们只返回。但是,如果发现不平衡,我们就返回一个。这个-1就代表“已崩塌”。这样,逻辑就变成了:如果左边返回-1。

2026-01-29 13:43:53 331

原创 算法训练营 Day14 - 二叉树 part02

226.翻转二叉树 (优先掌握递归)翻转一棵二叉树。这部分很简单,只需要把之前前序的递归方法中的根改成左右子节点交换就行。101. 对称二叉树 (优先掌握递归)给定一个二叉树,检查它是否是镜像对称的。递归三步法104.二叉树的最大深度 (优先掌握递归)给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明: 叶子节点是指没有子节点的节点。示例: 给定二叉树 [3,9,20,null,null,15,7],返回它的最大深度 3。

2026-01-29 08:06:15 401

原创 算法训练营 Day13 - 二叉树part01

了解 二叉树的种类,存储方式,遍历方式 以及二叉树的定义了解 二叉树的种类,存储方式,遍历方式 以及二叉树的定义个人而言,二叉树一直是最难理解和做题的一个类型,光是前中后3个遍历就已经很难记住了。所以这一章对我来说是至关重要,需要稳固掌握的。因此我会一步步把二叉树的概念都过一遍。:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。

2026-01-28 13:11:28 549

原创 算法训练营 Day11 - 栈与队列part02

简单的一句话规则:遇到数字就存起来,遇到符号就把最近存的两个数字拿出来算,算完把结果放回去。我们平时写,符号在数字中间。逆波兰式写成2 1 + 3 *,符号在数字后面。为什么要这么写?这对计算机非常友好,因为不需要括号,也不需要管乘除法优先于加减法,只要按照顺序读下去就能算出来。在这道题中,我们需要维护一个队列,这个队列内部的元素必须保持从大到小的顺序。队头 (Front):永远保存当前窗口内的最大值。队尾 (Back):保存可能成为未来最大值的候补元素。为了维持这个特性,我们在push和pop。

2026-01-28 08:28:59 618

原创 算法训练营 Day10 - 栈与队列part01

232.用栈实现队列232.用栈实现队列使用栈实现队列的下列操作:push(x) -- 将一个元素放入队列的尾部。pop() -- 从队列首部移除元素。peek() -- 返回队列首部的元素。empty() -- 返回队列是否为空。

2026-01-26 12:15:08 545

原创 算法训练营 Day9 - 字符串 Part02

今日任务151.翻转字符串里的单词卡码网:55.右旋转字符串28. 实现 strStr()459.重复的子字符串字符串总结双指针回顾151.翻转字符串里的单词给你一个字符串s,请你反转字符串中的顺序。是由非空格字符组成的字符串。s中使用至少一个空格将字符串中的分隔开。返回顺序颠倒且之间用单个空格连接的结果字符串。输入字符串s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。反转后的字符串中不能存在前导空格和尾随空格。

2026-01-23 08:39:43 611

原创 算法训练营 Day8 - 字符串 Part01

给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。给定一个字符串 s 和一个整数 k,从字符串开头算起, 每计数至 2k 个字符,就反转这 2k 个字符中的前 k 个字符。例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。我们以2k为for loop的前进速率。输入:["H","a","n","n","a","h"]输出:["h","a","n","n","a","H"]

2026-01-22 12:14:19 280

原创 算法训练营 Day7 - 哈希表 Part02

今日任务454.四数相加II383. 赎金信15. 三数之和18. 四数之和总结454.四数相加II给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500。所有整数的范围在 -2^28 到 2^28 - 1 之间,最终结果不会超过 2^31 - 1。

2026-01-21 10:12:38 639

原创 算法训练营 Day6 - 哈希表part01

总结一下,当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。但是哈希法也是牺牲了空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找。如果在做面试题目的时候遇到需要判断一个元素是否出现过的场景也应该第一时间想到哈希法!242.有效的字母异位词给定两个字符串s和t,编写一个函数来判断t是否是s的 字母异位词。示例 1:true示例 2:输出:false。

2026-01-20 16:01:48 633

原创 算法训练营 Day4 - 链表part02

我现在被换到了这对节点的后面,我现在的任务是负责连接【下一组】未处理的链表,不能让我以前指向的老二(Node 2)继续占着我的指针,也不能让我指向空。19.删除链表的倒数第N个节点给你一个链表,删除链表的倒数第n个结点,并且返回链表的头结点。示例 1:[1,2,3,5]示例 2:[]示例 3:[1]链表中结点的数目为sz你能尝试使用一趟扫描实现吗?这题非常好理解,先使用快慢指针让fast到n+1地,这样当他们一直走到fast = null的时候,slow正好在倒数第n个点的前一个。

2026-01-17 06:57:52 638

原创 算法训练营 Day 3 - 链表part01

这行代码的意思是:“返回虚拟头节点后面连着的那一串节点”。这就是我们处理完后的新链表。如果使用currentcurrent负责跑腿、移动、删除节点。dummy_head就像一个钉子,死死钉在链表的最前面,纹丝不动。不管current跑多远,dummy_head永远指向开头。如果直接移动dummy_headdummy_head就会跑到链表的中间甚至末尾。等你循环结束想返回链表头时,dummy_head已经不在开头了,你再也找不到回家的路了。

2026-01-16 10:00:36 635

原创 算法训练营 Day 2 - 数组part2

填1。当前方向Right。预判(0,1)。安全。-> 移动到(0,1)。(0,1): 填2。当前方向Right。预判(0,2)。安全。-> 移动到(0,2)。(0,2): 填3。当前方向Right。预判(0,3)。越界!转向Right->Down。新预判(1,2)。安全。-> 移动到(1,2)。(1,2): 填4。当前方向Down... 继续...这样就自然形成了一个螺旋。区间和前缀和 在涉及计算区间和的问题时非常有用!前缀和的思路其实很简单,我给大家举个例子很容易就懂了。

2026-01-15 13:47:59 38 1

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除