自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 代码随想录图论

而dfs搜索找下一个节点的时候,不用一个个遍历graph中的节点,而是只需要遍历当前节点能到达的节点,因为如果当前节点都到不了的节点,就没有必要往后遍历了。实际上就是回溯算法,区别在于:之前做的回溯的题目一般是列表里面一个一个元素遍历,所以在递归的时候有一个star_index变量,控制选与不选当前元素。因此递归的dfs的输入就变成了当前遍历的节点i。

2024-04-12 16:30:17 957

原创 Leetcode HOT 100

方法二:利用字母异位词排序之后是相同的这一特点构建哈希字典,键为排序后的单词组成的字符串。找数组或者列表中的相同元素,可以考虑用相同的属性作为dict的key,利用哈希分组。

2024-03-05 13:09:31 513

原创 代码随想录刷题

【代码】代码随想录刷题。

2024-01-24 19:07:45 404

原创 刷题第五十一天 84. 柱状图中最大矩形

【代码】刷题第五十一天 84. 柱状图中最大矩形。

2023-12-23 22:13:42 78

原创 刷题第五十天 503. 下一个更大元素 42. 接雨水

【代码】刷题第五十天 503. 下一个更大元素 42. 接雨水。

2023-12-23 10:27:18 57

原创 刷题第四十九天 739. 单调栈 每日温度 496. 下一个最大元素

碰到比栈顶元素大的就pop,把栈顶元素所在的索引赋值为当前元素的索引减栈顶的索引;碰到小的就压栈,直到碰到大的。求当前元素左边或者右边第一个比当前元素大或者小的元素。单调栈中元素的作用:存放遍历过的元素。单调栈:保证栈中的元素递增或者递减。和上一题类似,只不过多了一个映射。

2023-12-23 10:19:12 33

原创 刷题第四十八天 647. 回文子串 516. 最长回文子序列

s[j]的情况,就是判断能否加入s[i](dp[i][j-1])、s[j](dp[i+1][j])使得最长回文子序列更长。

2023-12-20 11:25:56 219

原创 刷题第四十七天 583. 两个字符串删除操作 72. 编辑距离

递推公式分成两部分,如果是遍历到两个字符相等了,那么就直接dp[i][j] = dp[i - 1][j - 1] 因为以i - 2结尾的word1和j - 2结尾的word2相同需要的步数和以i - 1的相等。dp[0][0]表示word1和word2都是空的情况,所以初始化的时候dp[0][j]就要等于j,意思是把word2变成空需要的步数,同理dp[i][0]要等于i,表示把word1变成空需要的步数。删除或者替换的情况都考虑,就是多一个dp[i - 1][j - 1]的情况。

2023-12-19 10:31:38 29

原创 刷题第四十六天 392.判断子序列 115. 不同的子序列

本题和昨天的1143 最长公共子序列的共同点在于都是求公共子序列的长度,不同的在于当s[i - 1]和t[j - 1]不相等的时候,不用去考虑dp[i - 1]的情况,因为本题最终要判断s是不是t的子序列,s里面不删除元素。统计s所有长度等于t的长度的子集,统计一下t在子集中出现了多少次。

2023-12-18 10:55:58 46

原创 刷题第四十五天 1143. 最长公共子序列 1035. 不相交的线 53. 最大子数组和

不相等的情况要考虑是因为本题可以不连续,所以在不连续的时候要把之前的最大值保留下来。

2023-12-18 00:46:54 49

原创 刷题第四十四天 300. 最长递增子序列 674. 最长连续递增子序列 718. 最长重复子数组

递推公式:如果第j个元素大于第i个元素,并且i < j。那么以第j个元素结尾的最长递增子序列的长度是所有的i的长度+1中最大的那个。## dp[i][j] nums1中以i - 1结尾的子数组和nums2中以j - 1结尾的子数组中的公共子数组的最大长度。和前一题相比多了连续,所以不用比较所有小于j的i,只要比较前一个元素就可以了。dp数组的含义:以第j个元素结尾的最长递增子序列的长度。最后返回dp数组中的最大值。

2023-12-17 10:19:33 50

原创 刷题第四十三天 309.买卖股票最佳时机+冷冻 714. 买卖股票最佳时机+手续费

dp[i][0] = max(dp[i - 1][0], dp[i - 2][1] - prices[i]) 因为有一天冻结,并且无限次交易,所以第i天持有的情况之一 就是第i-2天的时候卖掉的时候手上的现金 减掉今天的价格。#dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i] - fee) #因为每笔交易,所以统一在买入的时候收,涉及到买卖就再减掉fee。#dp[i][1] 第i天不持有股票,手上的最大现金。

2023-12-14 09:57:33 52

原创 刷题第四十二天 123. 买卖股票的最佳时机Ⅲ 188. 买卖股票的最佳时机Ⅳ

和前一题的限制在于只能买卖两次,所以dp数组多定义一个状态,分别表示第一次持有 第一次不持有和第二次持有 第二次不持有,然后进行更新。和前一题的差别就是可以多次买卖,所以定义一个三维数组,表示每次持有和不持有。注意初始化的时候 第一次持有和第二次持有都需要默认0-prices[0]

2023-12-13 11:37:34 59

原创 刷题第四十一天 121. 买卖股票的最佳时机 122. 买卖股票的最佳时机Ⅱ

dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + price[i]) 当天不持有的最大现金为 昨天就不持有或者今天卖出两者取最大。#dp[i][1] = max(dp[i - 1][1], 0 - price[i]) 当天持有股票手上的最大现金为 昨天就持有或者今天买的两者取最大。最后的结果就是dp[i - 1][0]和dp[i - 1][1]中的最大值。#dp[i][1] 当天持有股票,手上的最大现金。所以是dp[i - 1][0] - price[i]

2023-12-12 10:56:13 43

原创 刷题第四十天 198.打家劫舍 213.打家劫舍Ⅱ 337. 打家劫舍Ⅲ

不能同时偷首尾,那么就分两种情况考虑,偷第一家 不偷最后一家和不偷第一家,偷最后一家。第i个房间最多偷了多少钱为偷与不偷当前房间的金额最大的那个。dp数组表示偷到第i个房间最多偷了多少钱,

2023-12-12 09:34:57 44

原创 刷题第三十九天 139. 单词拆分

这道题关键在于dp数组的含义,指导含义了之后。

2023-12-11 10:26:55 35

原创 刷题第三十八天 322.零钱兑换 279.完全平方数

找最少需要用多少物品,装满j的背包 最少的物品是j-1, j-2, j-3到0的物品最少的那个 + 1。和上一题类似,只不过物品变成了完全平方数。

2023-12-08 11:49:57 40

原创 刷题第三十七天 完全背包概念 518.零钱兑换Ⅱ 377.组合总和Ⅳ

因为装满j的背包的种类由所有装满j-weight[i]背包的种类求和得到,因为所有装满j-weight[i]的背包都可以和i组成装满j的背包。和0-1背包的差别在于物品可以重复使用无限多次,所以在遍历背包的时候需要正序遍历,重复使用前面的状态。完全背包问题的遍历顺序 先物品还是先背包都可以,因为不影响状态的更新。因为存在顺序不同的序列,实际上求排列的数目,就是先遍历背包再遍历物品。计算装满背包有多少种类的问题的递推公式就是。先物品再背包是组合数,物品的顺序是不变的。先背包再物品是排列数,物品的顺序会改变。

2023-12-08 10:37:37 34

原创 刷题第三十六天 1049. 最后一块石头的重量Ⅱ 494. 目标和 474. 一和零

有一点思路:每个字符串就是一个物品,物品的价值就是1,有两个重量,一个重量就是0的数量 另一个重量就是1的数量。要同时装满背包的两个属性,求最大的价值,也就是子集最大的数量。dp数组的含义为从石头中任取,装满容量为_sum//2的背包的最大重量,因为只有尽量装满_sum//2 剩下的一堆石头和背包里的石头就是最接近的。装满容量为j的背包的总方法数量等于所有装满容量为j-nums[i]的背包方法数量之和。dp[i][j]: 装满i个0 j个1最多装多少个(dp[i][j])物品,最后返回dp[m][n]

2023-12-08 00:36:32 125

原创 刷题第三十五天 动态规划 0-1背包问题 416. 分割等和子集

放物品i的价值 dp[i - 1][j - weight[i]] + value[i] (当前物品的价值加上剩余空间的最大价值)第一行初始化根据物品0的重量和价值来,如果背包重量大于等于物品0 的重量的元素,初始化为物品0的重量,小于的话初始化成0.背包问题:每个物品都有自己的重量和价值,最多只能放的重量为m,最多的价值为多少。dp[i][j]: 下标为0到i的物品任取放进容量为j的背包里的最大价值。第一列初始化为0,因为背包容量为0的情况,最大价值就是0。dp[j] 容量j的背包能装的最大价值。

2023-12-05 11:15:51 48

原创 刷题第三十四天 343. 整数拆分 96. 不同的二叉搜索树

其中以j为头节点的二叉搜索树的数量为j-1个节点构成的二叉搜索树的数量乘以i-j个节点构成的二叉搜索树的数量的乘积,因为他们分别作为左树和右树。这样考虑的话对于2和3来说 最大乘积应该就是1 * 2 和1 * 3,和题目的要求有些不同,所以根据题目要求先返回n = 2或者3de情况,然后开始递推。以j为头节点的二叉搜索树的右树一定是由i - j个节点构成的,数量为dp[i - j]以j为头节点的二叉搜索树的左树一定是由j-1个节点构成的,数量为dp[j - 1]n-2 的最大乘积 * 2;

2023-12-04 11:10:09 27

原创 刷题第三十三天 62. 不同路径 63.不同路径Ⅱ

这道题目的路径因为限制了只能向下和向右,所以第一行和第一列可以直接初始化为1,初始化想明白了,后面动态规划的递推公式就和上楼梯类似了,到达每一个网格的路径是 到达这个网格向上那个网格的路径 和到达这个网格向左那个网格的路径之和。第二题在第一题的基础上多了障碍物,主要就是初始化得想清楚,一开始代码的逻辑把初始化和递推写在一起了,写的很复杂。分开处理就逻辑很清晰。

2023-12-02 11:49:28 606

原创 刷题第三十二天 动态规划启动 509. 斐波那契数 70. 爬楼梯 746. 最小花费爬楼梯

爬楼梯问题,只要想到到达第i层台阶只有两种方式,一种从i-1上来,另一种从i-2上来,所以递推公式就是到达第i层台阶的方式为第i-1层的方式 加上第i-2层的方式。多了一个从台阶向上跳的花费。递推公式就变成了第i层的花费是第i-1层的花费加上i-1向上跳需要的花费以及第i-2层的花费加上i-2向上跳需要的花费两者最小值。斐波那契数,递归解决,时间复杂度有点高。用动态规划,递推公式就是斐波那契的公式。

2023-12-02 00:57:52 34

原创 刷题第三十一天 738. 单调递增的数字 968. 监控二叉树

由于在 Python 中整数是不可变类型,因此您在。解决这个问题的一种方法是使用类变量而不是方法参数。所做的更改不会反映到。

2023-12-01 00:18:57 35

原创 刷题第三十天 435. 无重叠区间 763. 划分字母区间 56. 合并区间

先利用哈希来统计每个字母的最远出现位置,然后第二次遍历的时候,用left right来记录左右区间的位置,每次都比较当前右区间以及当前字母对应的最远位置,两者取较大值作为新的right,直到遍历到right的位置,说明已经遍历过的所有字母的最远位置就到这了。此时我们删除的标准就是比这两个区间谁的终点更远,局部最优就是每次都删掉终点更远的,这样就可以保证需要删除的区间数量最小,所以让下一个区间的终点等于这两个重叠区间终点较近的那个。

2023-11-29 10:28:55 42

原创 刷题第二十九天 860. 柠檬树找零 406. 根据身高重建队列 452. 用最少的箭引爆气球

所以people.sort(key = lambda x: (-x[0], x[1]))就表示对列表每个元素的第一个值进行降序,如果第一个值相同,那么第二个值进行升序。思路就是遍历一次,每次计算剩余的五元和十元的数量,如果数量小于0就return False,遍历完了都没小于0就return True。判断区间是否重叠,就是前一个的右边是否大于等于后一个的左边,如果小于,说明要多一根箭, 如果大于等于,那么就要再判断下一个在不在。

2023-11-28 23:57:28 24

原创 刷题第二十八天 1005. K次取反后最大化的数组和 134. 加油站 135.分发糖果

gas就是增加的油 cost就是减少的油,得到他们的差值数组diff来表示如果从当前站出发,起始的油,我们要保证出发站起始的油累积到最大,能最大程度保证有解。和最大子序和的想法有点类似,统计diff数组的最大子序和的起点就可以了,起点就在_sum刚开始变正数的第一个值,因为题目说了有解的情况就一定存在一个唯一的解,所以能确保这种思路找到的值就是起点。如果gas的累计值大于cost的累计值,那就一定有解。分两边遍历,从前向后只考虑右边大的情况。从后往前只考虑左边大的情况。

2023-11-27 11:10:51 27

原创 刷题第二十七天 122. 买卖股票的最佳时机Ⅱ 55. 跳跃游戏

一开始写了一个两层循环,每次都模拟一遍最大的跳跃过程。看了解析之后明白了,可以直接从覆盖范围的角度出发,计算每个点出发的最大覆盖范围,如果最后最大覆盖范围覆盖了最后一个位置就return true。题目的关键在于把收益细分为每日,因为提前知道了所有的价格,所以所有的上涨都可以吃到,所有的下跌都可以避免。模拟的过程要好好想想,这种数组模拟问题感觉一直想的不清楚。关键在于要搞明白自己需要定义哪些变量,变量的含义和起到的功能作用。注意python的for循环不支持动态改变变量的值,所以用while循环比较方便。

2023-11-26 02:56:46 29

原创 刷题第二十六天 贪心算法 455. 分发饼干 376. 摆动序列 53. 最大子序和

关键在于pre_diff的计算,不能每次都算,因为如果碰到单调有平坡的情况,也会result+1。所以应该在有峰值转换的适合让pre_diff = cur_diff。否则就保持pre_diff的方向不变。用count来初始化起始位置,如果count小于零,那么count等于0,即每次都从新的位置开始算,因为如果从当前位置算 肯定没有从新的位置算来的小。贪心的思路就是局部最优到全局最优;本题局部最优就是让当前的小朋友吃到满足其胃口的当前的最小尺寸,所以一开始需要都排个序。

2023-11-25 10:33:39 24

原创 刷题第二十五天 332. 重新安排行程

1. 回溯收集路径的时候加入一个cur参数,来记录当前到哪了,这样的话可以直接构建一维的list,初始的时候cur一定是JFK,后面每次递归cur就是tickt[1]自己写了一版,但是没有A,超时了。具体思路是和全排列类似,找出所有头尾相连的以JFK出发的路径 然后用字符串比较字典排序大小,返回最小的。3. 回溯函数加一个返回值,如果返回真,说明找到了,直接return,到主函数返回结果就行。2. 可以先对tickets进行sort,这样先找到的路径就一定是最短的。332.重新安排行程。

2023-11-24 11:28:19 26

原创 刷题第二十四天 491. 递增子序列 46. 全排列 47.全排列Ⅱ

和之前的去重方法类似,这次是树枝去重,因为结果都是在树枝上收获的,两个逻辑,因为是全排列,所以所有的元素都会用上,如果新的元素已经被用过了,那就直接continue;另外一点就是如果i>0,说明在水平的树层,然后碰到相等的值,并且是头叶子,那么直接continue。看了视频之后理解了树层去重,用到uset,每层循环开始之前定义一个uset来记录每层用过的元素,如果新元素出现过了,那就continue。主要是去重的思想,和子集的想法类似,但是这里给出的数组不是有序的,不能改变顺序。491. 递增子序列。

2023-11-22 11:11:42 28

原创 刷题第二十三天 93. 复原IP地址 78. 子集 90.子集Ⅱ

和上一题做的分割回文串类似,都需要切割字串,这里需要判断是否是有效的ip地址,注意不能有先导0:即不能有00 或者000出现,但是0是可以的。和组合类似,只不过这次搜集所有的节点。93. 复原IP地址。

2023-11-21 23:19:55 32

原创 刷题第二十二天 39. 组合总和 40. 组合总和Ⅱ 131.分割回文串

2. 切割的字串可以用start_index 到 i 的左闭右闭区间表示,因为python字符串的切片是左闭右开的,所以要写成[start_index: i+1]1. 使用used数组来判断当前的值是否被用过了,如果没用过,说明在根节点,并且当前值与前一个值相等,就可以直接跳过,因为相同的情况在前一个值全都考虑过了。3. 递归是走树的深度,循环是走树的宽度,所以代码运行的逻辑先是走递归走到底,就是最左边走到最深处,然后回溯返回的过程就是一步步的走树的宽度。131. 分割回文串。

2023-11-21 10:08:38 28

原创 刷题第二十一天 216. 组合总和 17. 电话号码字母组合

剪枝的时候考虑目前已经添加了len(subset)个元素,还需要k-len(subset)个元素,遍历的话遍历到总的元素9 减掉还需要的元素k-len(subset)之后的数值+1就可以了,因为for i in range 是左闭右开,所以还需要再加一。和前面的组合问题不同,这次的回溯是从两个不同的集合取值,所以每次递归调用的时候,需要一个参数index来控制去不同的集合取值。注意回溯的时候 subset pop的同时_sum要减一。17. 电话号码字母组合。

2023-11-19 09:22:33 60

原创 刷题第二十一天 回溯算法 77.组合

结束条件:当收集到的subset长度等于k,就将subset.copy()加入result中,不能直接result.append(subset) ,这会导致subset改变会影响到result。2.4 排列问题, N个数按一定规则全排列,有多少种方式。剪枝操作:每次循环内部递归的时候,可以从当前值的下一个开始循环。2.3 子集问题, N个数的集合中有多少符合条件的子集。2.1 组合问题,N个数中按一定规则找出k个数的集合。2.2 切割问题, 字符串按一定规则有多少切割方式。几个重要的点:结束条件;

2023-11-17 10:59:05 42

原创 刷题第二十天 108. 有序数组转BST 538. BST累加 669. 修剪BST

右左中遍历,双指针,中间循环的逻辑就是当前节点的值更新为当前节点的值加上前一个节点的值,并把pre的值更新。分区间构建的思想,每次取中间节点新建根节点,返回的时候分别让左右两边接住。538. BST转化为累加BST。108. 有序数组转BST。669. 修剪BST。

2023-11-16 23:22:09 47 1

原创 刷题第十九天 235. BST最近公共祖先 701. BST中的插入操作 450. 删除节点

此时直接返回插入的节点,然后被下面接住,如果是val小于root.val 那么让root.left等于返回的结果;遍历的时候,如果节点的值大于p,q的值就返回左子树,小于就返回右子树,如果正好在p,q的值中间,就返回当前节点,说明找到了。3. 左右都不为空:首先将左子树移到右子树最左侧节点的下面,然后按左为空右不为空处理,返回右节点。1. 左右都为空的叶子节点,直接返回None到上一层,让父节点接住。2. 左为空或者右为空,返回不为空的节点。450. 二叉搜索树删除节点。遍历到空的时候作节点插入。

2023-11-15 23:51:13 26

原创 刷题第十八天 530.二叉搜索树最小绝对差 501. 二叉搜索中的众数 236. 二叉树最近公共祖先

和计算深度类似,只要碰到节点相等了 就把当前节点返回 然后左右根接住,最后判断左右子树那边接到了 就继续向上返回,直到两边都接到了然后就返回root。4. 判断目前的累计值是否等于最大计数,如果相等 收获结果,如果大于,则清空数组;没解决的问题:为什么把倒数后两个if的位置交换 答案就不对,想半天没想明白。二叉搜索树中序遍历完就是一个有序数组,判断数组最小的相邻值 然后返回。2. 前序节点的值等于当前节点的呃值,计数+1。1. 前序节点如果不存在,计数为1。236. 最近公共祖先。

2023-11-15 00:27:01 129

原创 刷题第十七天 654. 最大二叉树 617.合并二叉树 700.二叉树中的搜索

思路是如果遍历到空节点就return None 找到了就return当前节点,分别记录左树和右树的返回值,最后如果有root节点记录下来 就返回。两棵树同时遍历,如果遇到一棵树节点为空 则返回另一棵树的节点,如果都不为空则节点的值累加。二叉搜索树 中序遍历完一定是递增的数组,所以先中序遍历一下 然后判断数组是不是递增。没有看到题目搜索树的定义,直接按普通的树遍历了。3. 构建左节点等于新构建的左子树。4. 构建右节点等于新构建的右子树。98. 验证二叉搜索树。654. 最大二叉树。617. 合并二叉树。

2023-11-14 02:08:01 38 1

原创 刷题第十六天 513. 找树左下角的值 112. 路径总和 106.中序后序构造二叉树

如果子节点为空,说明当前节点就是叶子节点了,那么return回去的时候,上一层的path并没有增加,所以不需要有退回的操作。换句话说叶子节点的值是在最后一层递归加上的,所以返回的时候path的值就是除了当前叶子节点的值。定义一个search_path函数递归遍历 记录下每条路径的值为path, result中加入path的值,因为是通过子节点是否为空来返回,所以path的更新要放在最前面。层序遍历一下,每次行开始的时候记录一下每行首位的值,遍历结束之后就是左下角的值。513. 找树左下角的值。

2023-11-13 10:51:11 26

空空如也

空空如也

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

TA关注的人

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