自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 代码随想录第59天

1.下一个更大元素II有两种方法:1.把两个一样的数组拼起来:这种写法确实比较直观,但做了很多无用操作,例如修改了nums数组,而且最后还要把result数组resize回去。resize倒是不费时间,是O(1)的操作,但扩充nums数组相当于多了一个O(n)的操作。2.走两边数组可以版本二不仅代码精简了,也比版本一少做了无用功!最后在给出 单调栈的精简版本,即三种情况都做了合并的操作。

2023-06-11 16:04:35 1054 1

原创 代码随想录第58天

这里answer[2]和answer[4]出现问题,关键是如果遍历元素小于等于栈头元素时放入元素后,出现大于栈头的元素,但是没有一次性弹完,等到出现遍历的元素比弹剩下的元素大的时候,他中间隔了好多元素,但是j从遍历的元素开始减,所以会出错,会使answer[弹剩下的元素的下标]没有结果,还有会使answer[某个元素的下标]第二次赋值。加入T[5],T[5] > T[4] (当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况),将T[4]弹出,同时计算距离,更新result。

2023-06-11 11:17:59 898

原创 代码随想录第57天

看这个直观一点:

2023-06-10 19:23:24 652

原创 代码随想录第56天

1.两个字符串的删除操作dp[i][j]:以i-1为结尾的字符串word1,和以j-1位结尾的字符串word2,想要达到相等,所需要删除元素的最少次数。2.确定递推公式当word1[i - 1] 与 word2[j - 1]相同的时候,dp[i][j] = dp[i - 1][j - 1];当word1[i - 1] 与 word2[j - 1]不相同的时候,有三种情况:情况一:删word1[i - 1],最少操作次数为dp[i - 1][j] + 1。

2023-06-10 16:17:40 886

原创 代码随想录第55天

首先他是方法数,然后dp[i][j]是以s[i-1]为结尾的s的子序列中找以j-1为结尾的t(dp数组的含义),其实他是由dp[i-1][j]为基础推出来的,只不过是当s[i - 1] 与 t[j - 1]相等时多了一个情况,就是以s[i-1]为结尾去代替dp[i-1][j]种方法中的结尾字母,最后是把他们加起来,相当于dp[i - 1][j - 1]是增量。所以当s[i - 1] 与 t[j - 1]相等时,dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];

2023-06-10 12:19:48 908

原创 代码随想录第53天

如果text1[i - 1] 与 text2[j - 1]不相同,那就看看text1[0, i - 2]与text2[0, j - 1]的最长公共子序列 和 text1[0, i - 1]与text2[0, j - 2]的最长公共子序列,取最大的。因为最长重复子数组是要求连续的,你递推的时候dp[i-1][j-1]的值一定是和以i-2和j-2为结尾连起来最大长度,然后如果A[i]==B[j],那么再加1,连续的长度有增加了;其实也就是说A和B的最长公共子序列是[1,4],长度为2。

2023-06-10 09:21:29 1058

原创 代码随想录第52天

1.最长递增子序列本题中,正确定义dp数组的含义十分重要。为什么一定表示 “以nums[i]结尾的最长递增子序” ,因为我们在 做 递增比较的时候,如果比较 nums[j] 和 nums[i] 的大小,那么两个递增子序列一定分别以nums[j]为结尾 和 nums[i]为结尾, 要不然这个比较就没有意义了,不是尾部元素的比较那么 如何算递增呢。这样想有点抽象。看个具体的例子:2.状态转移方程位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列 + 1 的最大值。

2023-06-03 19:05:44 617

原创 代码随想录第51天

如果i为1,第1天买入股票,那么状态1递归公式中需要计算 dp[i - 1][1] - prices[i] ,即 dp[0][1] - prices[1],那么大家感受一下 dp[0][1] (即第0天的状态二)应该初始成多少,只能初始为0。那么dp[i][0] = max(dp[i - 1][0], dp[i - 1][3] - prices[i], dp[i - 1][1] - prices[i]);今天卖出了股票(状态三),同上分析,dp[0][2]初始化为0,dp[0][3]也初始为0。

2023-06-03 14:53:19 798

原创 代码随想录第50天

如果price[i-1]比price[i]小:dp[1][i]就要换了成-price[i-1]了,dp[1][i-1]和,dp[1][i]都一样了,用当天 的和昨天的dp[1]没区别,dp[2][i]=dp[1][i-1]+price[i];其实dp[2][i]=max(dp[2][i-1],dp[1][i]+prices[i]);如果price[i-1]比price[i]大:dp[1][i]就要换了成-price[i],但是这个是没有正利润的,所以dp[2][i]=dp[2][i-1],不影响结果。

2023-06-03 10:30:27 391

原创 代码随想录第49天

出现正利润之后就是max(dp[i-1][1],dp[i-1][0]+prices[i])这两个的比较了,不要把前面的dp[i-1][1]写成0,不然一旦出现正利润之后就都是dp[i-1][0]+prices[i]。同样dp[i][1]取最大的,dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);那么dp[i][0]应该选所得现金最大的,所以dp[i][0] = max(dp[i - 1][0], -prices[i]);(我感觉和贪心的思路一样)

2023-06-02 20:06:01 388

原创 代码随想录第48天

1.打家劫舍:动规五部曲分析如下:dp[i]:考虑下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i]。 2.确定递推公式决定dp[i]的因素就是第i房间偷还是不偷。如果偷第i房间,那么dp[i] = dp[i - 2] + nums[i] ,即:第i-1房一定是不考虑的,找出 下标i-2(包括i-2)以内的房屋,最多可以偷窃的金额为dp[i-2] 加上第i房间偷到的钱。如果不偷第i房间,那么dp[i] = dp[i - 1],即考 虑i-1房,(注意这里是考虑,并不是一定要偷i-1房,这是

2023-06-02 19:02:36 365

原创 代码随想录第46天

"apple", "pen" 是物品,那么我们要求 物品的组合一定是 "apple" + "pen" + "apple" 才能组成 "applepenapple"。"apple" + "apple" + "pen" 或者 "pen" + "apple" + "apple" 是不可以的,那么我们就是强调物品之间顺序。而本题其实我们求的是排列数,为什么呢。除非是先用 "apple" 遍历一遍,再用 "pen" 遍历,此时 dp[8]已经是1,最后再用 "apple" 去遍历,dp[13]才能是1。

2023-05-29 22:35:49 110

原创 代码随想录第45天

1.爬楼梯:下面的代码是写的是一步可以走1到m步。。2.确定递推公式在中我们都讲过了,求装满背包有几种方法,递推公式一般都是dp[i] += dp[i - nums[j]];本题呢,dp[i]有几种来源,dp[i - 1],dp[i - 2],dp[i - 3] 等等,即:dp[i - j]那么递推公式为:dp[i] += dp[i - j]3.dp数组如何初始化。

2023-05-28 15:43:33 112

原创 代码随想录第44天

1.动态规划:完全背包理论基础。

2023-05-28 14:05:03 123

原创 代码随想录第43天

这里的意思是(用第一句来解释一下)在你遍历完物品[i]后,你的背包重量为1了,就是这个物品已经放进去了,你的背包容量为5,这时你的背包容量为4,因为dp[i]数组的含义是满足背包容量i的情况有dp[i]种,所以在当一个重量为1的物品已经进入背包后还剩下dp[4]种方法凑成容量为5的背包,但是这不代表只有dp[4]种方法,他还有其他情况,把这些全部加上才是dp[5],其实还可以看最后一句,你背包刚好满了(5已经放进去了),不是只有一种方法了吗?中dp[j]才不会初始值所覆盖。

2023-05-28 09:02:06 75

原创 代码随想录第42天

首先从dp[i][j]的定义出发,如果背包容量j为0的话,即dp[i][0],无论是选取哪些物品,背包价值总和一定为0。如图:在看其他情况。状态转移方程 dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);可以看出i 是由 i-1 推导出来,那么i为0的时候就一定要初始化。dp[0][j],即:i为0,存放编号0的物品的时候,各个容量的背包所能存放的最大价值。

2023-05-27 13:34:14 61

原创 代码随想录第41天

我举这个例子,其实就说做题的严谨性,上面这个代码也可以AC,大体上一看好像也没有毛病,递推公式也说得过去,但是仅仅是恰巧过了而已。

2023-05-26 16:51:13 61

原创 代码随想录第39天

从递归公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 中可以看出,一定是从左到右一层一层遍历,这样保证推导dp[i][j]的时候,dp[i - 1][j] 和 dp[i][j - 1]一定是有数值。这里要看一下递推公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1],dp[i][j]都是从其上方和左方推导而来,那么从左到右一层一层遍历就可以了。dp[i][j] :表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路径。

2023-05-23 19:16:13 268

原创 代码随想录第38天

第2层台阶是只有2种方法,然后从第3层开始就是:假设是第i层,这层的上上i-2层,有dp[i-2]种方法到第i-2层,这时在爬2层,就到了i层,注意这是在每种dp[i-2]个方法后面加了一个步骤不是加了一个方法,然后i层的上层i-1层也是这样,爬一层就到了i层,因为一次只能走一层或者2层,所以dp[i-2]+dp[i-1]=dp[i];一定是选最小的,所以dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);这个一看就是从前往后;

2023-05-23 10:12:16 56

原创 代码随想录第37天

因为叶子节点是不会有安装摄像头的,因为浪费子节点,虽然摄像头放头节点也是浪费父节点,但是头节点只有一个但是叶子节点有好多个,叶子节点浪费的覆盖节点不是头节点能比的,所以思路是从下往上遍历(也就是后序遍历),叶子节点的父节点安装摄像头,然后每隔2个节点放一个节点,直到遍历到头节点。就是万一头节点的左右节点都被覆盖到,也就是上面图的最后一种情况:这时头节点上面没有节点,上面不会有摄像头了,所以这时要在头节点上按一个摄像头。说完了非空节点,轮到空节点了,遍历中如果遍历到空节点的话返回什么呢?

2023-05-21 14:21:18 101

原创 代码随想录第36天

这里result里面的是左边界小的,而且是对result里面的数组进行操作,也就是说改变的是左边界小的数组的右边界,而不是左边界大的,也就是intervals上的数组的左边界,这里注意左边界小的右边界不一定就小,所以要加一个max。2.然后遍历第一个字母的最大区间,左闭右闭,如果出现字母的右边界超过第一个字母的右边界,那就更新右边界,遍历的最大值也要更新,直到里面的字母的右边界都小于最终的右边界 ,输出最终的右边界的下标。3.把2中右边界的下一位当作第一个字母重复2的操作,直到遍历完数组。

2023-05-21 09:12:06 75

原创 代码随想录第35天

在设定result的时候是在数组不为空的情况下,这最少也有一根箭,然后在判断第二个数组,如果和第一个数组有重叠那么更新一下右边界相当于跳过这两个数组了(也不完全是跳过了,因为万一更新了还是重叠第3个数组,也就是上面第2幅图,但是也是没问题的)然后那个第一个数组的箭就在这个重复的区域射出;全局最优:完成全部账单的找零。但仔细思考一下就发现:如果把气球排序之后,从前到后遍历气球,被射过的气球仅仅跳过就行了,没有必要让气球数组remove气球,只要记录一下箭的数量就可以了。2.根据身高重建队列。

2023-05-20 15:19:55 97

原创 代码随想录第34天

因为如果出现这种情况,那说明区间1<0,区间2>0,但是上面贪心思路中说了,一旦出现curSum<0,就会更新i变成i+1,curSum重新开始计数,也就是说假设是从x开始计数,curSum是不会小于0的,但是实际是遍历到i时curSum是小于0的,这个是条件,假设和条件相违背了,所以假设是错的。按我的思路是1 2 3 1 2 2 1 总数为12,答案是1 2 3 1 3 2 1 总数为13,这样其实是有问题的,因为最后一个87是大于2的但是他们的糖果是一样多的,所以是错的。

2023-05-20 09:33:36 44

原创 代码随想录第32天

他的思路比我的简单,他是求覆盖范围只要能到结尾就输出true,而我的是求数为0且不是最后一位时的情况,求0前面的数能不能跳过他,不能就输出true,能就找下一个0,如果都可以就输出true,这道题没有0的情况是肯定是true的,curDistance是当前覆盖最远距离的下标,nextDistance是遍历当前最远距离时能覆盖的最远距离的的下标,注意都是下标!,这个范围内最小步数一定可以跳到,不用管具体是怎么跳的,不纠结于一步究竟跳一个单位还是两个单位。都可以,都是对curDistance的判断。

2023-05-17 17:02:29 45

原创 代码随想录第31天

只有一个值或者两个一样的值时输出1,两个不一样的值输出2,在代码中他是假设初始点前面还有一个和初始点一样的值,这样最开始的preDiff=0,默认result=1(默认最后一个值是一个峰),当只有两个不一样的值的时候,只会遍历到第一个,第一个是左平右不平,result++,输出2,当两个一样的值的时候,只会遍历到第一个,左平右也平,result不++,最后只会输出1.其实默认始末点是两个峰值,(两个值不一样),但是不能让result的初始值为2,因为万一真只有两个一样的值不就错了吗。

2023-05-14 21:50:52 46

原创 代码随想录第29天

path.empty()&&nums[i]<path.back()//path的最后一位是path.back(),并且前面要判断path不是空不然会报错。注意前面的前提一个是i>0确保i-1不小于0,后面那个一是确保i-1不小于0二是确保不是自己这层的第一个和上一层的比较而是同层比较。所以要加他的前一位的used的值是不是为false(上面用1和0表示true和false)数字的范围是-100到100,所以定义used[201]个,used[0]是-100的。

2023-05-13 10:18:16 87

原创 代码随想录第28天

bool isIP(const string& s,int start,int end){//这个下面的数字和字符的转化注意点。2.5.5.2. 这样后面那个点号删掉就直接输入到result里面去,不可能的事,要把所有的数字都用上,所以不能这么写。//这里是要求是在s[start]到s[end]的区域不是整个s。如果上面的输入后面少一位的话,最小长度还是2,但是255.255.111.3,这个就不能解释了。}//这个是在第三个点号后面没有数字时的情况。他的思路是直接用点号为分割点在原来的s上分割。

2023-05-10 22:36:40 33

原创 代码随想录第27天

3.这个输入的数组要排序,不然要是最大的在前面,就算有答案也会输出空。2.当起始位置坐标大于等于s的长度时说明已经找到了一组path了。,注意上面的函数调用的第2个参数是字符的长度。3.判断回文数时是s在判断不是path。

2023-05-10 18:07:58 38

原创 代码随想录第25天

答:根据题目要求取出一个数字,定义一个字符串来代替字符串数组中的这个数字代表的字母们,然后遍历这个字符串就行了。后面那个-‘0’必须要.1.在定义result和s时,看清楚result是字符串数组,s是字符串。1.刚看到这题的时候不知道怎么才能让数字和字母做到一一映射。思路和组合是一样的,只不过多加了一个元素总和的限制。2.而且就算映射了,什么才能遍历字母并回溯呢?3.当digits为空的时候的情况别漏了。3.如何取出输入的字符串中的每一位数字。

2023-05-04 22:01:36 61

原创 代码随想录第24天

举个例子,n = 4,k = 3, 目前已经选取的元素为0(path.size为0),n - (k - 0) + 1 即 4 - ( 3 - 0) + 1 = 2。来举一个例子,n = 4,k = 4的话,那么第一层for循环的时候,从元素2开始的遍历都没有意义了。列表中剩余元素(n-i) >= 所需需要的元素个数(k - path.size())(这个是关键!在集合n中至多要从该起始位置 : i <= n - (k - path.size()) + 1,开始遍历。

2023-05-03 18:12:59 20

原创 代码随想录第23天

如果是第二种的话输出的是只有3,所以第二种有一个问题就是如果遍历到一个节点不满足[low,high],但不代表他的左子树或者右子树都不满足[low,high],上面那个例子就是0虽然不满足要求,但是不代表他的右子树都不满足要求,所以要遍历他的右子树寻找第一位满足要求的节点并返回,正好第一位就满足。所以返回2,让他等于3的左节点。让root在[low,high]后,找他的左子树和右子树中符合 [low,high]的,至于为什么要找左子树右子树中符合 [low,high]的看上面递归的解析。

2023-05-03 15:21:26 20

原创 代码随想录第22天

第五种情况不好理解的话可以把要删除的节点模拟成头节点,删除头节点后,旧的头节点的右节点变成新头节点,因为旧头节点的右子树的最左面节点都比旧头节点的左子树上的节点大,所以把旧头节点的左子树都移到旧头节点的右子树的最左面节点的左孩子上。说实话着实没想到删除直接delete,然后关于每一种情况中的return ,他是删完后向上原路递归返回,最后返回新的树,2.在第五种情况中,cur要的是root的右子树的最左边那个节点,所以在定义cur的时候别定义错了。1.在要做连接操作的时候,记得在删节点前保存一下原节点。

2023-05-01 17:51:02 18

原创 代码随想录第21天

count是全局变量,如果是第一个节点的话,count=1,然后如果接下来如果值一样的话,count++,后面有几个加几个,一直下去,但是如果是不同的话,那么count就会变成1,重新开始算频率。在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。我的思路是找两个节点的深度,如果一样的话,返回他们的父节点,如果不一样就返回深度低的那个 ,题目中关键的点是节点的值不重复!函数体内不能修改形参a的值。

2023-04-27 21:31:05 23

原创 代码随想录第20天

这两个if不要写习惯了里面判断条件写成root->left,如果两个都是判断他左右节点是不是空的话,其他的不变,这样只要根节点的左子树中没有要求的值的话,他就输出null。和迭代法的中序遍历挺像的,就多了几行代码,一开始看到时候有点懵,看来还得多看看迭代法的中序遍历.在原来遍历中序数组往result输入节点值那行代码换成了判断前后节点的大小。唯一要注意的是:题目中说了输入的数组大小一定是大于等于1的,所以我们不用考虑小于1的情况,那么当递归遍历的时候,如果传入的数组大小为1,说明遍历到了叶子节点了。

2023-04-25 21:33:11 21

原创 代码随想录第19天

题目中要求的值是深度最深的那一层的最左边那个值。递归法的思路其实是比较每个叶子节点的深度,最深的那个的值是题目要求的,如果最下面那层有多个叶子节点,因为是先遍历左边的,所以最下面那层最左边的会被记录进去,之后要是遇到同层的,因为depth=maxDepth所以不能被赋值了。思路是从根节点出发,用sum减去路径上的值,直到叶子节点,如果到了叶子节点count不是0,那这条路径不是要求的,返回false,回溯,,如果count=0,那么就是,返回true,之前的每层递归都返回true,连结果都返回true。

2023-04-24 21:49:44 56

原创 代码随想录第17天

后序遍历到每个叶子节点,以当前叶子节点的高度为一,向上递归,以每个非叶子节点为传入递归的节点,比较他的左子树的高度和右子树的高度,一旦发现有返回值为-1的,之后往上的递归都不用比较了,直接return -1,因为就执行if (leftHeight == -1) return -1;直到返回第一层递归,返回-1;字符串数组加字符串:result.push_back(Spath);1.字符串加字符是: Spath+=to_string(path[i]);要记住题目问的都是左叶子之和,右叶子是不加的。

2023-04-23 18:58:39 23

原创 代码随想录第16天

遍历到每一个叶子节点,根据当前depth和之前遍历的result比较,小的话,result=depth,否则返回,继续遍历到其他叶子节点,因为要比较谁小,所以result初始值要最大。问:在遍历完根节点的左子树后,回到node为根节点的那次递归,接下来应该开始判断根节点的右子树,我想问一下这时的depth是1还是遍历完左子树后的depth?最小深度是从根节点到最近叶子节点的最短路径上的节点数量,为什么是叶子节点,因为最小深度就是到某个没有子节点的节点,这个就是叶子节点。假设根节点深度为1,越往下越大。

2023-04-22 16:01:40 22

原创 代码随想录第15天

不能把这句去掉然后在加节点时判断,因为这样的话他比较的节点就不是对称的了。每一层都创建一个一维数组,再把元素加进去,最后直接加到二维数组中,就会有这种效果[[,,],[,,,],[]]需要注意的是当他left=null,right=null时(不是第一次循环)也就是到了最底下在下面一层,这时return true返回上一层循环。注:交换的是节点(数值加指针)第一次交换后根节点的左边所有节点和右边所有节点交换了。相当于复习了递归遍历,迭代法遍历,统一迭代法遍历,层序遍历了。不只是交换了根节点的左右孩子。

2023-04-22 11:26:45 17

原创 代码随想录第14天

中序遍历是把所有节点都加完了,在从后面反向加到result里面,后序遍历也差不多是这个。看是看的懂,但是在弹出的时候他是一次while循环弹一个,如果要连续弹两个的话,在第一弹完后,把第2个先弹出去,在加回来后面再加一个null,这样就可以把他弹出去了。这个统一迭代法他加节点的规律是和他遍历的方向是反的,比如中序遍历是左中右,而他加节点那一块的代码时右中左,其他的前序遍历,后续遍历,中序遍历一样。进栈的是541,cur=1的左节点是空开始弹出1,cur=1的右节点,是空,弹出4,这样就能返回父节点了。

2023-04-19 17:22:03 26

原创 代码随想录第13天

1.滑动窗口最大值:我的思路是先排序,在创建一个队列,遍历数组,进一个出一个,每次返回队尾的值。优先级队列:优先级队列(priority_queue)其实,不满足先进先出的条件,更像是数据类型中的“堆”。优先级队列每次出队的元素是队列中优先级最高的那个元素,而不是队首的元素。这个优先级可以通过元素的大小等进行定义。比如定义元素越大优先级越高,那么每次出队,都是将当前队列中最大的那个元素出队。个人感觉这就是所谓“优先级”的定义。

2023-04-17 22:10:39 95

实训.zip

实训.zip

2022-12-29

空空如也

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

TA关注的人

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