- 博客(30)
- 收藏
- 关注
原创 代码随想录打卡第三十天 动态规划
dp[j]应该表示为:当背包最大容量为j时,放入i和不放入i所能产生的最大价值是多少。如果最大容量为target且当前所能产生的最大价值为target时,表示存在。转化为本题为,加入在不超过当前最大和的情况下,放入哪些元素能使的当前的目标和最大(接近target)有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i]。01背包:每件物品只能用一次,对于每件物品,即放或者不放。右边的dp[j]表示上一层即dp[i-1][j]得到的结果。
2025-06-17 22:40:37
287
原创 代码随想录打卡第二十九天 动态规划
本题注意初始化的时候,第一排和第一列有障碍物之后的位置都是0,初始化方式有点笨了,其实只要在循环判断加一条就行了obstacleGrid[i]==0就行了。对于某一个元素是障碍物的话,当前路径数也是0.其余和第一题一样。本题也相对简单,初始化第一行和第一列,然后对于每一个位置,路径数等于上面位置和左边位置的路径数之和。没什么思路,直接看的题解。对于dp[i]的含义倒是想到了,单对于递推公式属实想不出来。
2025-06-16 23:25:49
146
原创 代码随想录打卡第二十八天 动态规划
爬到当前层,可以是剩两步跳两步,可以是剩一步跳一步,所以等于前两个方式之和。这道题不难,初始值和递推都给了。主要是熟悉动态规划的方法。
2025-06-16 23:16:27
127
原创 代码随想录打卡第二十七天 贪心
如果后面的数字比前面的数字大,则前面数字需要变为9,后面数字-1。我的方法很笨,可以直接转化为字符数组的。将最小右边界更新为找最大右边界就行,注意如何退出循环,被折磨了很久都少了一个区间。
2025-06-16 23:07:09
121
原创 代码随想录打卡第二十六天 贪心
想到了统计每一个字母最后出现的位置,但是没有想到运用数组,也没想到更新数组值的方式。最后动态的更新i和最大下标的位置也很巧妙。先按照起始区间排序,如果下一个区间的起始位置小于当前重复区间的右边最小值,说明这个区间和前面区间也是重合的。此时无需更新间的数量。否则开始计算下一个重合区间。先按照起始区间排序,记录每次重复区间最小的有边界,统计尽可能多的非重复区间,减去重复区间的数量就是需要移除的区间。
2025-06-16 22:54:02
119
原创 代码随想录打卡第二十五天 贪心
先从前往后遍历,碰到比左边大的,就比左边+1,其余就给1。再从后往前遍历,碰到比右边大的,并且给的糖果更少或者相同的,加1。然后根据每个元素的位置依次插入元素。有10找10,无10找5,没5结束。没有好的思路,看题解。
2025-06-16 22:33:57
160
原创 代码随想录打卡第二十四天 贪心
很直白的想到,问的是最大和,就当作每次要涨的前一天买入,要下跌就卖出。直接求第二天更大的差值的和就行了。一样的思路,不同的是每次记录本次可达的位置中拥有最远可达位置的下标。每次判断当前可达下标的最远可达下标,并更新最远可达下标的位置。如果到了末尾则返回。每次排序后对最小的值取反。
2025-06-10 23:25:12
192
原创 代码随想录打卡第二十三天 贪心
本题很容易想,最大的安排即最小的浪费,即饼干应尽可能满足胃口和饼干大小差不多的人,所以对两个数组排序。如果优先考虑胃口,那么要将胃口从大到小排序,如果满足胃口小于饼干,则同时减。如果优先考虑饼干,那么饼干从小到大排序。可以很直白的想到,如果加入下一个元素没有使得元素变负数,则可以添加,如果变成了负数,则完全清空结果集。用result来表示下标位置思路很好。局部最优:删除单调坡度上的节点(不包括单调坡度两端的节点),那么这个坡度就可以有两个局部峰值。整体最优:整个序列有最多的局部峰值,从而达到最长摆动序列。
2025-06-10 23:15:02
253
原创 代码随想录打卡第二十二天 回溯
排列问题和组合问题最大的区别就是,组合我们一般需要startInde来记录位置,但是排列需要遍历所有元素。所以不再需要startIndex,因为本题不含重复元素,所以可以解决的简单一点,用一个used数组来记录是否被使用过就行。解题思路是想到了利用map来记录是否出现过当前元素,因为无法进行排序。但是对于map的创建位置以及在元素比较上,错误使用了i和i-1来比较,但是有可能i-1不在path中,所以需要path.getLast来比较。
2025-06-09 00:29:40
210
原创 代码随想录打卡第二十一天 回溯
本题解题思路是,如果当前i和startindex相同,并且当前元素是0,那么当前元素是作为单独元素加入path的,加入后应该开始下一层递归。本题难点在于对先导0和剪枝的处理。注释掉的部分是我通过了但是写的十分丑陋的代码。可能更好理解一点,所以也放在这里温故而知新。没什么难度,注意一下去重就行。
2025-06-09 00:09:14
129
原创 代码随想录打卡第二十天 回溯
往下树深遍历时,相同的元素是可以重复选取的,每次添加元素就将当前元素置为true。如果前一个相同的元素没有使用过,即为false,,代表同一层。还有另一个思路:如果当前i > startIndex时,说明这是同一层,也说明不用再遍历这个元素。本题较难,周天解决的,周六硬时没想明白。组合时选择一个元素加入,切割是选择一个位置加入切割,本质上是一样的。因为对于每一个循环来说,start是不变的,i是一直递增的。本题需要注意的是,每个重复可以重复选取,所以递归时我们递归传递的参数就不是i+1,而是 i。
2025-06-08 23:56:15
136
原创 代码随想录打卡第十九天 回溯
本题上来就没想到如何用数字映射字母,卡哥用数组映射并添加两个空数组使问题豁然开朗。在组合时没什么难度。但是这里有另一个问题,递归时,下一层遍历的应该是下一个数字对应的字母,所以需要把下一层的数字传进去,并下个数字对应的字符串遍历应该从0开始。在这里给出回溯标准模板,碰到回溯都可以考虑如何运用到模板里。下面关于能直接套用模板不再赘述思路。
2025-06-08 23:29:27
163
原创 代码随想录打卡第十八天 二叉树(二叉树完结)
最直白的解法为求出有序数组,然后累计求和,遍历时逐一赋值。但是注意到本题是从右至左累加。遍历顺序正好为递减序列,和反中序遍历效果一致。采用反中序和双指针很容易解出答案。需要掌握前中后序反序能达到什么效果。如果当前节点比最小值还小,只需要修建右子树。如果比最大值还大,只需要修剪左子树。如果正好处于中间,则左子树指向待修剪的左子树,右子树指向待修剪的右子树。这道题和利用前中序构造数二叉树类似。取中间节点作为根节点,然后将右边数组作为右子树,左边数组作为左子树。
2025-06-04 23:09:06
119
原创 代码随想录打卡第十七天 二叉树
这道题十分绕脑子,首先需要找到节点,如果没找到直接返回NULL。如果找到了,则需要判断当前节点是叶子节点还是仅有左子树还是仅有右子树还是左子树右子树都有,根据不同情况返回不同节点,注意递归返回需要有节点接住返回值。利用二叉搜索树特性,如果P,Q均小于当前节点,则递归左子树。如果P.Q均大于当前节点,递归右子树。其余情况均返回当前节点。如果比当前节点大,则递归右子树,如果比当前节点小,递归左子树。知道碰到叶子节点决定是构造左子树还是右子树。
2025-06-04 23:00:08
89
原创 代码随想录打卡第十六天 二叉树
本题和上题一样,最直白的解法为新建一个MAP,逐一计数,在找其中的最大值,最后输出所有值为最大值的元素。但是本题也可以利用双指针解法。如果遍历到当前元素和前一个元素不一致吗,初始化当前元素的个数为1,如果一直,则计数+1,如果当前计数超过之前记录最大值,则更新最大值并清空集合。注意,可能存在多个最大值,所以和当前最大值相等时应该直接加入集合。此时只需要记录前一个节点,并计算和当前节点的差值,如果小于当前result,则更新当前result.如果P,Q分别在当前节点的左右,则当前节点就为最近的公共祖先。
2025-06-04 22:47:51
155
原创 代码随想录打卡第十五天 二叉树
使用递归时没考虑右子树的左子树比根节点小的情况。看了题解,知道二叉搜索树中序遍历的特性,知道特性之后使用中序遍历就简单了很多。针对卡哥说的如果存在比long.min_value更小的情况,使用pre节点记录上一个节点也时不错的思路。如果两个节点都为空,合并结果也为空,直接返回空。如果都不为空,则使用val的和构造新节点,如果只有一个为空吗,则返回另一个节点。找到最大的元素,然后左边元素递归构造左子树,右边元素递归构造右子树,注意下标范围。层序遍历秒了,递归采用了二叉搜索树的特型,也是不错的递归思路。
2025-05-30 23:02:11
276
原创 代码随想录打卡十四天 二叉树
采用迭代法,层序遍历每个元素,如果每一层的第一个元素是叶子节点且循环结束不再有新元素,则输出第一个节点的val。二叉树后续和中序、前序和中序可唯一确定一颗二叉树。可根据以下步骤构造二叉树。本体和找路径一样,每次递归时把当前元素加入数组,判断到叶子节点时计算是否满足,否则回溯。
2025-05-30 22:26:27
118
原创 代码随想录打卡第十三天 二叉树
采用层序遍历,如果当前节点的左孩子的左右孩子都为空,说明这个节点左孩子是个左叶子,加入sum。如果左子树和右子树的高度差超过1 则非平衡二叉树,作为单层递归条件。卡哥关于完全二叉树性质可以了解,但是使本题复杂了。如果是空,高度返回0,作为退出条件。按照求节点个数的方法,采用递归秒了。卡哥的递归法没太看懂,先标记在这。碰到叶子节点,加入结果集。每遍历到节点,加入路径。根据以上思路开始递归。
2025-05-29 23:29:46
131
原创 代码随想录打卡第十二天 二叉树
但在中序遍历时需要注意,采用左中右递归时,把左边翻转完后到交换中间时,左边已经到了右边,此时再翻转右边,就导致之前左边的子树重复翻转,而右边子树没有递归翻转。这里需要注意和求最大深度不同的是,当左子树为空或者右子树为空时,说明当前节点不是叶子节点,不能代表最小深度,需要求另一边不为空的子树的最小高度+1;确定递归边界条件,只有左右子树均存在且val相等时,才去递归判断左子树的左子树和右子树的右子树,左子树的右子树和右子树的左子树。递归处理左右子树,最大深度为1+左右子树的最大深度。
2025-05-27 21:40:43
233
原创 代码随想录打卡第十一天 二叉树
这里需要注意的是,我们需要使用一个变量来记录当前层的所有节点是否遍历完成,才能加入所有的子节点。这也就是说,我们在根据本层队列循环遍历时,处理到当前节点,需要将节点本身从队列里面弹出,并把子节点加入队列。最开始做的时候基于最小改动原则,我只打算在list加入sublist即当前层级的最大值,使用了Java Lambda表达式:subList.stream().max((i, j) -> i-j).get()获取最大值,这里案例有五个没通过:即0,-2147483648,2147483647。
2025-05-26 23:14:47
328
原创 代码随想录打卡第十天 栈和队列
看了卡哥的方法,,理解思路为:我们的队列不需要存储所有的三个值,我们只存储当前的最大值,这样每次压入队列时,无需去k的复杂度去计算最大值,时间复杂度降为o(n);如果当前为数字,则直接压入栈,如果为字符,则弹出上面两个元素,计算值并压入当前栈。拿到该题的思路即为使用一个队列,遍历数组,并求队列最大值。单调队列如下:队列内元素永远单调递增或递减,且不改变元素顺序,和优先级队列不一样。压入元素如果比peek()大,则弹出前面所有元素,如果比peek小,加入元素。如果移除的值是当前队列出口元素,则移除。
2025-05-25 20:54:54
314
原创 代码随想录打卡第九天 栈和队列
所以在寻找模式串开头位置字串和i前面相同的字串即为j-1位置和模式串开头位置子串,这时候j回到next[j-1],,如果此时还不相等,则j继续回到当前j的j-1。我们在定义j和i表示前缀末尾和后缀末尾时,要记住一个概念,及位置i的next值即也为最长公共前后缀的长度,而j的位置代表前缀末尾,即位置i的next值即为当前j下标的位置。用两个栈实现,栈A即为进,栈B即为出。如果当前为左括号,直接压入栈,如果当前为右括号,则判断栈顶是否为对应左括号,如果是,弹出栈顶,如果不是,说明不匹配。
2025-05-25 20:08:07
222
原创 代码随想录打卡第八天-字符串
清理字符串前面和后面的多余空格,把难以处理的情况之际排除掉。然后遍历剩余的字符串,如果当前字符和下一个字符都为’ ‘,那么当前字符不加入sb,当前字符右移一位,这样是为了排除多余的空字符。然后对sb的字符串进行操作。KMP算法的难点在于如何求解next数组,且明白next数组的值具体代表什么含义,掌握了next数组即掌握了KMP算法。没看到KMP算法之前只有暴力求解的思路,看了KMP算法之后,决定烧电脑CPU而不是烧自己CPU.这道题采用库函数截取k之前的字符串和k之后的字符串,加起来就做完了。
2025-05-22 21:34:25
174
原创 代码随想录打卡第七天-字符串
本题和三数之和类似,想到了再引入一个指针的算法,但是对于重复值和去枝考虑不清楚,导致花了大量时间没做出来,看了讲解之后异常清晰,本题基本不算自己做出来,还需要笑话。(len/2(2*k))遍历即可,做复杂了但还是做出来了,题解代码更简洁。本题需要考虑最后一部分单独的处理,前面以2。
2025-05-21 21:59:39
191
原创 代码随想录打卡第六天-哈希
本题首先想到了两个数组一起处理,两两分别处理,但在使用哈希map存储元素上没有思考出更好的解决方案,题解的使用sum和出现的次数可谓是点睛之笔,本题不需要返回下标,只需要返回个数,所以统计sum出现的次数即可,getOrDefault的方法使用也很醍醐灌顶,还需继续打磨思维能力。看了卡哥的双指针思路,首先对数组排序这是没想到的,这块可以作为以后的思维方式,排序后首先对于最大的sum有了判断,第二就是对重复元素的值的处理十分巧妙,去除重复元素这里的细节需要注意。例如:2025-05-20周二晚上。
2025-05-20 22:28:29
165
原创 代码随想录打卡第五天-哈希集合
遍历数组,查找目标值和当前值的差值是否在哈希MAP中,如果在,则停止遍历。采用哈希set,将第一个数组中不重复的值加入第一个哈希set,遍历第二个数组,如果在第一个哈希set里面,则把该值加入第二个哈希set。最后将set转化为数组,这里转化为数组的方式不太熟,需要记忆。采用数组记录每个字母出现过的次数,数组索引用26个字母作为唯一索引,遍历第二个字符串时如果存在则–,最后判断是否存在不为0的数据。如果存在重复值,则一定不为快乐数,反之,则一定会等于一,关键在于求和以及判断是否为重复数据。
2025-05-19 22:06:37
207
原创 代码随想录打卡第四天-链表
看到该题很久都没有明白题目是什么意思,还以为是给了两个链表,让我找存在哪些元素相同,返回元素相同时的第一个节点,故在本地使用了两次反转链表实现了我以为的功能。后来看了题解,给出的两个链表是在某一个节点同时指向了一个节点,后面的解题思路就是看卡哥的从后对齐,然后找第一个指向同一个节点的节点了。总体而言没有太好的解决思路。看了讲解后意识到,包含虚拟节点的任意四个节点操作都完全一致,这也提供了递归的思路。即遍历当前链表,如果集合里面没有当前节点,则加入map,如果有当前节点,说明存在环,返回当前节点即可。
2025-05-17 22:25:21
209
原创 代码随想录打卡第三天-链表
本题一上来给我的难点就在于需要自己构造节点类和链表,因工作中很少使用链表,已经忘记如何初始化一个链表,罪过。此外就是对下标index的判断,即插入删除是节点指针应当走到哪里然后操作节点,想明白这里后这道题即可迎刃而解。本题难点在于对头指针的操作,引入虚拟头节点后解决这一问题,即使得头节点的操作和普通节点保持了一致。
2025-05-17 00:19:49
175
原创 代码随想录打卡第二天-数组
采用快慢指针方式,如果和大于目标值,计算当前长度,满指针+1,并循环判断移动后是否仍大于目标值,如果是则继续慢指针+1。z注意累计求和时要减去满指针当前值。如果小于目标值,则快指针+1,直至完成遍历。本题思路混乱,陷入循环怪圈,看了卡哥思路才勉强参照解题。
2025-05-15 22:54:58
173
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人