- 博客(65)
- 收藏
- 关注
原创 每日一题——96. 不同的二叉搜索树
遍历头节点,确定头节点后,按二叉搜索树的特性,左边为比头节点小的数,节点数为头节点-1,右边为比头节点大的数,节点数为总数-头节点。不同头节点下:左边的可能性*右边的可能性。这里我疑惑的是怎么能确定左边的节点数和右边的节点数呢。
2025-03-19 11:05:32
138
原创 每日一题——343. 整数拆分
这种情况表示将 i 分割成 j 和 i-j 两部分后,对 i-j 继续进行分割,并利用之前计算得到的 dp[i - j] (规模为 i-j 的子问题的最优解) 来计算当前的结果。dp[i - j] 表示规模为 i-j 的子问题的最优解,将这个最优解乘以 j, 意味着把规模为 i 的问题分解成j和i-j,且规模为i-j的部分采取最优分割策略。: 将当前计算出的最佳分割结果与已经存储在 dp[i] 中的最优解进行比较,并更新 dp[i], 保证 dp[i] 始终存储的是到目前为止找到的最优解。
2025-03-16 10:57:10
231
原创 每日一题——63. 不同路径 II
这样下一步将从左+从右,前面有障碍物的话就是+0,表示了无法从这里到下一格的情况,只是另外一个方向的移动到达的。有障碍物,就不能从这里到下一个格子。这里如果有障碍物就不更新它对应的值,也就讨论有障碍物的情况。
2025-03-15 20:52:22
275
原创 每日一题——746. 使用最小花费爬楼梯
遍历边界为cost.size,因为是要爬到顶,及最为一个元素之上,而不是到最后一个元素就结束了。本来觉得是一道很简单的dp题,但没看清楚提议是cost代表从i开始要花费的价值。我们这里定义f[i]为到i所需要的最少力气,有两种途径可以到i。-从i-1跨一步上来,即f[i-1]+cost[i-1]-从i-2跨两步上来,即f[i-2]+cost[i-2]
2025-03-13 13:34:23
151
原创 每日一题——763. 划分字母区间
找到每个字母的最远出现位置,遍历s,如果i就是这个区间所有位置的最远出现位置,说明这个区间的所有字母都只出现再left到i了,此为一个区间,更新left为i+1,找下一个区间。
2025-03-09 22:44:15
169
原创 每日一题——435. 无重叠区间
这里更新边界就相当于删除一个重叠区间,删除的是覆盖的广的那个区间(减少和其他区间重叠 的风险)找到最大重叠区间,就删除。
2025-03-07 12:03:18
149
原创 每日一题——452. 用最少数量的箭引爆气球
这里通过更新右边界解决,将上一个重叠区间的右边界更新为两个气球的右边界min(也就是交集),再判断下面的气球是否和这个交集相交就可了。如果重叠的气球就不需要单加一个箭,如果不重叠就需要增加一支箭去射它。难点在于,两个气球重叠了,如何判断下一个气球是否再和他们重叠。
2025-03-06 12:18:31
198
原创 每日一题——406.根据身高重建队列
先按照身高重大到小排队,然后根据前面应该有多少人去调整位置,把people往前插入就好。i的后面都是比他低的,就算后面的数移动到前面,也不改变i前面比它高的people的个数。
2025-03-03 11:16:10
177
原创 每日一题——135.分发糖果
第二遍主要考虑左比右高的情况,且取的为最大值,i-1比i低的话,更新后i的糖果依然比i-1多(因为第一遍遍历完的结果就是i的糖果比i-1多,第二遍更新后i的糖果只会大于等于之前的糖果值,也就依然比i-1多)。如果i-1比i高的话,那第一次的遍历是不更新i的糖果值的,第二次遍历,遍历到i了,再下一步到i-1,就会更新i-1的糖果值,使其比i的糖果值高,因此成立。-右边比左边分高的话,更新是从左边累计过去的,依次比左边高,,这种意思。初始值都为1,然后从左向右遍历,讨论右边的孩子比左边分高的情况。
2025-03-01 11:46:36
270
原创 每日一题——134. 加油站
原因:如果0~i中间点有符合条件的(也就是从这里开始后半段和>0),那么再根据到全区间和>0(到i的储存油量为负),前半段一定是<0的,那么这是,就会把中间点作为一个新的起点了,与一直累计判断到i不符,矛盾。接着,按照贪心思路寻找起点,如果从0开始,到i,储存的油量为负了,那这个区间就没有 能作为起点的index,从i+1开始,寻找新的起点,判断是否符合条件。首先要满足的条件是:总油量一定要大于总消耗,也就是gas的总和>cost的总和。否则,这个环路是不成立的,中间一定会有断开的地方。
2025-02-28 12:04:28
150
原创 每日一题——1005.K 次取反后最大化的数组和
如果没有负数了,就选最小的证书反复反转,这样要不然不变,要不然就只有他变负,对结果的削弱最小。无非是选最大的负数反转变正。
2025-02-27 11:29:32
168
原创 每日一题——45.跳跃游戏 II
这里还有点没想通,增加count和当前覆盖值的关系,不应该加了count,才会有覆盖的吗,目前的nextcount不是得加了才能占为己有的吗。
2025-02-26 11:30:03
238
原创 每日一题——55.跳跃游戏
因为cover可能会比数组长度更大,不及时更新break的话,后续i++,会大到溢出nums长度,就会报错。贪心策略:覆盖的最大值,如果能覆盖到结尾,那就可以跳跃、这里的结尾判定要写在循环里,更新了cover之后。
2025-02-25 11:05:51
218
原创 每日一题——122. 买卖股票的最佳时机 II
哎,,,这些思路是怎么想到的啊,我什么时候能自己就反应出来。算相邻两日的利润差,如果利润>0,就保持买入状态,获取利润。贪心策略:收集正利润。
2025-02-24 12:55:08
216
原创 每日一题——53. 最大子数组和
result的作用是记录最大的结果,每当count比result大了,说明找到了新的连续区间最大和,此时将结果更新为当前最大的和(即count),count继续向后遍历寻找。才根据各种判断条件舍弃和保留count。这样就不会错过:如果当前连续和为正数,但后面都是负数,会将总和削弱,但不会将总和削到负数,此时我们前面的记录就能保证记录到的是没被削弱的和。count用于遍历迭代整个数组可能的区间的连续和,当count取到更大的值,就将它赋值给result,此时的位置也就是连续区间的终止位置。
2025-02-22 14:15:27
248
原创 每日一题——376. 摆动序列
单调区间有平坡:在只有摆动变化的时候更新prediff,不然prediff =0,curdiff>0的时候记录一次,中间平坡,prediff变化,prediff = 0,curdiff>0的时候记录一次,最后prediff>0,curdiff<0的时候记录一次,中间就重复了,但中间的位置实际是prediff>0,curdiff>0,由于相同数值的情况,prediff更新为0,导致这种情况也被算成了一个极值,是错误的,所以只在。将整个序列抽象到坐标轴上,这里指的摆动也就是坐标轴上的极值。
2025-02-21 19:59:15
209
原创 LDA模型用pyLDAvis进行可视化ascii编码报错及解决方法
报错:UnicodeEncodeError: 'ascii' codec can't encode characters in position 18-20: ordinal not in range(128)n_job的问题,因为默认并行处理时,系统文件名有中文就会报错,添加n_jobs=1即可,如下。
2025-02-20 19:32:38
317
原创 每日一题——455.分发饼干
因为饼干是符合条件才移动的。如果饼干在for循环遍历,如果最大的饼干不能满足最大的胃口,那胃口就达不到移动的条件。饼干向后移动,只会越来越小,胃口因为达不到条件也永远不会移动,所以找到for循环遍历完了所有的饼干,结束了,都找不到能满足的情况。这里的for循环只能用胃口遍历,而不能用饼干遍历。贪心策略:用最大的饼干满足胃口最大的孩子。
2025-02-20 13:15:30
146
原创 每日一题——37.解数独
-在所有棋盘都填满了的情况下,就不会在走到后面的路劲判断true和false的情况了,这时棋盘都满了,则是找到了合法解,在最后的部分就return true;这里我纠结的问题是为什么前面return false和return true的情况都有了,结尾还要再返回return true。返回return bool值,判断当前路劲是否合法。直接引用传入board ,修改board的数值。
2025-02-19 21:25:37
253
原创 每日一题——51. N 皇后
返回值和参数:返回依然void,结果在全局变量result中,参数当前行数row,棋盘尺寸n,以及棋盘chessboard。若此时的位置,[row][i]合法,则放置皇后,随后向下递归找一下行中皇后的位置。叶子节点,当递归深度row == n的时候,将此时的结果放到result中。-因为for循环遍历选每一行的皇后,一行只会选一个(选了其他的会回溯)-这里的chessboard为什么不像之前的回溯一样设为全局变量?递归的深度就是棋盘的行数,for循环的宽度则为棋盘的列数。
2025-02-17 12:16:24
353
原创 每日一题——47. 全排列 II
但实际上一个used也就可以完成上面的逻辑,可以看到代码中对usedx和usedy的条件判断是不冲突的。两个相同的树a,b,树枝上可以重复选取,但树层上不行(会产生重复的全排列)。usedx完成此逻辑。与全排列1不同的就是这里有重复的数字,因此设计到去重。一个树a,树枝上不能反复选取,usedy完成此逻辑。去重依然就用树层去重,树枝不去重的原理。一个used即可实现所有功能。
2025-02-16 13:26:10
149
原创 每日一题——46.全排列
因此,在递归时,需要考虑到数字组合可以重复出现,也就是树层可以重复选择数字,不用担心选到与前面相同的组合,因为往后选择的数字顺序不同,与前面就不是一个全排列了。回溯出口:选取的全排列path的size和数组nums的size相同,所有数都被选了。但不能选取重复的数字,因此在向下递归时,需要一个used数组来区分当前数是否已经在全排列中,如果在,就不能再选。同样的数字组合,不同的排序,是两个不同的全排列。依然是回溯,这与前面的不同就是要区分顺序了。在递归时,就可以从整个数组中来选数字。
2025-02-15 12:55:18
239
原创 每日一题——491.非递减子序列
代码:思路:依然是回溯三部曲,一开始想着按之前选子集那道题一样先排序然后数组used去重但不行,这里给的是数组,不能更改他原有的顺序。去重逻辑依然是数层去重(防止产生相同的答案组合),树枝不去重(不重复选元素,但允许选两个一样的数)这里去重用到了unordered_set,无序set,每层都定义一个新的set,专门记录该层使用过的数递归到下一层后,又会定义新的set因此,只需要在加入数的时候对set更改,回溯时不用更改(因为这个set只管一层)
2025-02-14 12:18:38
363
原创 每日一题——90. 子集 II
出口这里是startindex == nums.size()而不是startindex == nums.size()-1。所以要在处理完nums.size()-1(合法),将要处理nums.size()(不合法)的时候切断,因为此时nums.size()-1传经来的状态是will,不是already。如果用第二种,会导致合法的索引nums.size()-1漏掉,会直接得到一个值全为value,size尺寸的vector。因为传进来的数是即将处理的数,不是已经处理的数;这里也就是前面题目的知识点结合。
2025-02-13 19:52:53
290
原创 每日一题——78.子集
纵向回溯:向后挑选的具体过程,以i+1迭代,使得能在不同于当前数字的后面的数中为集合选择数字。通过回溯来遍历到不同的挑选情况。(这一个位置选i+1,不选i+2;或是选i+2,不选i+1)差别为:这里要收集所有的组合,而不是和之前一样到了return的节点才返回。因为没有规定集合的长度,所以只要path发生了更新,就是新的符合要求的集合。横向遍历:依次选择起点位置,以某个数开始,向后挑选集合。总体回溯思路依然和前面差不多。
2025-02-11 14:11:51
196
原创 每日一题——93.复原ip地址
迭代逻辑:切割思路,以startindex为起点,遍历i,截取startindex到i的序列串,如果合法,(竖向)便以i为新的起点(startindex)截取后续的,直到将序列划分为四段(通过pointnum=3追踪,即有三个断点,每截取一段+1),若都合法便添加到result中,(横向)再回溯,向后移动1位i。-参数值,输入的字符串s,起始位置startindex,断点数pointnum。可以通过*s.begin()+i+1的方法获取到元素。-返回值void,结果存在全局变量result中。
2025-02-10 12:39:48
346
原创 每日一题——40. 组合总和 II
但后面想通了:for循环中i++迭代,从小到大遍历,处理到i的时候,i-1一定是已经被处理过了,used[i-1]一定是先从false变成true(向下递归的时候,不需要去重),再true变为false(回溯完成),不会有我纠结的那种情况,所以可以放心让used[i-1]=false的时候,跳过i。这里我疑惑很久的点是used[i-1]=false不还能代表一种情况:i-1这个数一直都是出厂设置状态,没有被选取过,所以更应该在used[i-1]=false的时候选择i,而不是true。
2025-02-08 23:03:56
385
原创 每日一题——39. 组合总和
如果直接写,当前面的某次遍历i不符合条件了,则会这一层的for循环,candidates中从i到后面的所有数都不能被遍历,就错过了这些数的组合可能。第二,对于剪枝这里,不能直接在for循环遍历中,写剪枝条件:sum+candidates[i] <= target。2.先排序candidates,从小到大,i越界了,后面的数比i更大,就也会造成越界,不会因为提起中断而错杀无辜。但实际上,这里越界了,后面可能有比i小的数,加上后不会大于target,依然有正解的可能。
2025-02-07 15:55:52
249
原创 每日一题——电话号码的字母组合
1.出口:当index等于digits的size,即已经搜索完index的所有数,结果已经存在全局变量result,所有直接return;以及全局变量映射表、result、中间string序列s_temp。根据digit在映射表中找到它映射的字符串letters。string、vector用的push_back。index,追踪做到第几位数字了和查找数字。针对letters中的每个字母一次搜索遍历。digits序列(找到要做映射的数字)stack、queue用的push。
2025-02-06 11:17:50
174
原创 每日一题——216.组合总和
逻辑便是,从startindex~9中,选择一个数,再从startindex+1(大1位的数)继续选择。返回值则是为空,结局存在全局变量中,函数变量则为n,k,开始位置startindex和当前组合总和n。纯暴力的话就是k个循环,遍历能得到总和为n的几种可能性。回溯出口则为找到了sum = n的数字组合。或是非法:数字已经到k了但sum不为n。但是k的范围会很大。
2025-02-05 16:32:46
173
原创 每日一题——77. 组合(剪枝优化)
如果已经选了path.size个数,那还需要选取的数个数为k-path.size。因为开始startindex是从1开始,所以边界也要再+1;所以1个数只用遍历一次,选了该数后后面就不能再遍历选取。题目要求从n个数选k个数组合,且组合中数的顺序无关。从n中开始选,就要是n-(k-path.size)优化主要是体现在for循环对i的限制。
2025-02-04 13:58:13
217
原创 每日一题——538. 把二叉搜索树转换为累加树
因为二叉搜索树的大小顺序排列为左中右,所以是按右中左的顺序累加。先加(处理)右节点,traversa(node->right)再处理中,加上右节点的值,用pre记录上一节点的值。正常返回:一棵树的右中左节点都已经处理完成、相当于递增有序数组,从末尾向前依次累加、边界:节点为空,直接return。
2025-02-02 20:31:47
168
原创 每日一题——108. 将有序数组转换为二叉搜索树
是因为若left和right都为很大 的int时,有超过int_max,爆int的风险。这样写,而不是直接int mid = (left+right)/2;返回值及参数:有序数组nums,左右边界left、right。递归逻辑:二分确定中间值为root,再左右递归确定子树。若left>right,数组已空,返回null。若完成root的构造,返回root。
2025-02-01 20:11:16
157
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅