- 博客(37)
- 收藏
- 关注
原创 day38|leetcode 322零钱兑换,279.完全平方数,139.单词拆分
(2)确定递推公式:dp[j-coins[i]]就是凑成j-coins[i]所需的最少的硬币个数,加上coins[i]就是dp[j]即dp[j-coins[i]]+1,由于求的是最小值,所以dp[j]=min(dp[j-coins]+1,dp[j]);(2)确定递推公式:如果确定dp[j] 是true,且 [j, i] 这个区间的子串出现在字典里,那么dp[i]一定是true。(2)确定递推公式:dp[j]=min(dp[j-i*i]+1,dp[j]);(1)dp[j]含义:和为j的完全平方数的。
2025-02-04 22:15:45
937
原创 day37|完全背包基础+leetcode 518.零钱兑换II ,377.组合总和II
小明的行李箱所能承担的总重量是有限的,问小明应该如何抉择,才能携带最大价值的研究材料,每种研究材料可以选择无数次,并且可以重复选择。dp[i] [j]的含义:表示从下标为[0-i]的物品,每个物品可以取无限次,放进容量为j的背包,价值总和最大是多少。完全背包与01背包的不同在于01背包的不同物品每个都只可以使用一次,但是完全背包的不同物品可以使用。按照当前的遍历顺序,dp[]={1,2,2}和{2,2,1}会被当作一组。按照当前的遍历顺序:dp[]={1,2,2}和{2,2,1}会被当作两组。
2025-02-02 19:21:53
1110
原创 day36|(dp)leetcode 1049. 最后一块石头的重量 II , 494. 目标和 , 474.一和零
0/1 背包:每个物品只能选一次,不能重复选择。多重背包:每个物品可以选择多次,但有最大数量限制。本题中的二进制数组中的每个元素都只能放进一次背包,是多维01背包dp[i] [j]含义:最多有i个0和j个1的最大子集的大小递推公式:dp[i] [j]=max(dp[i] [j] ,dp[i-zeroSum] [j-oneSum]+1);
2025-01-22 15:53:55
949
原创 day51|dfs与bfs的应用:岛屿数量,岛屿面积
题目描述:给定一个由 1(陆地)和 0(水)组成的矩阵,你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而成,并且四周都是水域。你可以假设矩阵外均被水包围。输入描述:第一行包含两个整数 N, M,表示矩阵的行数和列数。后续 N 行,每行包含 M 个数字,数字为 1 或者 0。输出描述:输出一个整数,表示岛屿的数量。如果不存在岛屿,则输出 0。方向控制0011011020-12103031-1。
2024-12-19 16:36:06
273
原创 day50|DFS,BFS
给定一个有 n 个节点的有向无环图,节点编号从 1 到 n。请编写一个函数,找出并返回所有从节点 1 到节点 n 的路径。每条路径应以节点编号的列表形式表示。输出所有的可达路径,路径中所有节点的后面跟一个空格,每条路径独占一行,存在多条路径,路径输出的顺序可任意。后续 M 行,每行包含两个整数 s 和 t,表示图中的 s 节点与 t 节点中有一条路径。注意输出的序列中,最后一个节点后面没有空格!第一行包含两个整数 N,M,表示图中拥有 N 个节点,M 条边。如果不存在任何一条路径,则输出 -1。
2024-12-18 21:19:37
371
原创 day35|01背包理论基础,leetcode 416.分割等和子集
背包空出物品i的容量后,背包容量为j - weight[i],dp[i - 1] [j - weight[i]] 为背包容量为j - weight[i]且不放物品i的最大价值,那么dp[i - 1] [j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值。根据二维数组中的 dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+vale[i]);第i件物品的重量是weight[i],得到的价值是value[i]。
2024-12-15 11:42:46
952
原创 day34|leetcode 62不同路径,63.不同路径II
2.递推公式:dp[i] [j]只可能从dp[i-1] [j]或者dp[i] [j-1]两个方向推过来,所以dp[i] [j]=dp[i-1] [j] =dp[i] [j-1]3.dp数组初始化:dp[0] [j]=1,dp[i] [0]=1;从(0,0)到(0,i)只可能有一条路,到(0,j)也同理。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。1.dp[i] [j]含义:从(0,0)出发到(i,j)有dp[i] [j]条路径。机器人的移动路径中不能包含。测试用例保证答案小于等于。
2024-12-02 19:57:59
347
原创 day32|leetcode 509.斐波那契数,70.爬楼梯,746.使用最小花费爬楼梯
递推公式:dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]),因为可以选择一次爬一阶还是两阶。意思是:dp[0]=0,dp[1]=0,从0或者1开始并不需花费,只有向上爬才要花费。个台阶向上爬需要支付的费用。递推公式:dp[i]=dp[i-1]+dp[i-2]递推公式:dp[i]=dp[i-1]+dp[i-2]dp数组如何初始化:dp[0]=0,dp[1]=1。dp数组如何初始化:dp[1]=1,dp[2]=2。dp[i]含义:爬到第i阶有dp[i]种方法。
2024-11-30 14:05:24
485
原创 day31|leetcode 56. 合并区间 , 738.单调递增的数字 , 968.监控二叉树
例如:332--->(3<2,3--)--->322(2-->9)--->329(3>2-->3--)--->229(2-->9)--->299。从后往前遍历,如果前一位数大于后一位就把前一位数一直减,直到前一位小于等于后一位,然后把后一位设置为9。(4)利用后序遍历,从小往上遍历,如果遍历完了,根节点还是无覆盖状态就在根节点放一个摄像头。输入:intervals = [[1,3],[2,6],[8,10],[15,18]]解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
2024-11-30 11:52:24
486
原创 day30|leetcode 452. 用最少数量的箭引爆气球, 435. 无重叠区间 , 763.划分字母区间
因为由图可以发现,如果不更新右区间,那么4-8这个气球又会被当作可以和7-12一起被射爆,这样就会得出一箭射爆前三个气球的错误结 论,但是实际上,前两个最多在6位置被射爆,实际需要两支箭,所以要更新右边界,取小值。有一些球形气球贴在一堵用 XY 平面表示的墙面上。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。: 通过排序让区间尽可能的重叠,然后开始删除,用左或右边界排序都可以。处射出一支箭,若有一个气球的直径的开始和结束坐标为。返回一个表示每个字符串片段的长度的列表。
2024-11-30 10:11:14
453
原创 day29|leetcode 134. 加油站 , 135. 分发糖果 ,860.柠檬水找零 , 406.根据身高重建队列
编号为 4 的人身高为 4 ,有 4 个身高更高或者相同的人排在他前面,即编号为 0、1、2、3 的人。此时油箱有 = 0 + 4 = 4 升汽油。因此 [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]] 是重新构造后的队列。输入:people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]输入: gas = [1,2,3,4,5], cost = [3,4,5,1,2]输出:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
2024-11-27 21:35:14
685
原创 day28|leetcode 122.买卖股票的最佳时机II ,55. 跳跃游戏 ,45.跳跃游戏II , 1005.K次取反后最大化的数组和
解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4。随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3。从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。解释:选择下标 (1, 2, 2) ,nums 变为 [3,1,0,2]。输入:nums = [3,-1,0,2], k = 3。
2024-11-26 21:02:42
1079
原创 day27|leetCode 455. 分发饼干,376.摆动序列,53. 最大子数组和
其中一个是 [1, 17, 10, 13, 10, 16, 8] ,各元素之间的差值为 (16, -7, 3, -3, 6, -8)。(3)只有两个不同元素时pre(num[i]-num[i-1]),cur(num[i+1]-num[i])操作悬空指针,统一判为2。解释:整个序列均为摆动序列,各元素之间的差值为 (6, -3, 5, -7, 3)。输入:nums = [1,17,5,10,13,15,10,5,16,8]输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
2024-11-25 21:45:45
703
原创 day25|leetCode 491.递增子序列,46.全排列 ,47.全排列 II
换用哈希表法,可以使用unordered_set或者数组,本题数值范围在-100 <= nums[i] <= 100,范围比较小,我采用数组来记录已经使用过的元素。输出:[[4,6],[4,6,7],[4,6,7,7],[4,7],[4,7,7],[6,7],[6,7,7],[7,7]]输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]](1)所需结果都是叶子结点,当path.size()==nums.size()时,收割。给定一个不含重复数字的数组。
2024-11-24 21:39:19
408
原创 day24|leetCode 93.复原IP地址 , 78.子集 , 90.子集II
正好由四个整数(每个整数位于0到255之间组成,且不能含有前导0),整数之间用'.'分隔。和是IP 地址,但是和是IP 地址。给定一个只包含数字的字符串s,用以表示一个 IP 地址,返回所有可能的,这些地址可以通过在s中插入'.'来形成。你重新排序或删除s中的任何数字。你可以按顺序返回答案。
2024-11-24 13:25:25
1134
原创 day23|leetCode 39. 组合总和 , 40.组合总和II , 131.分割回文串
再循环到第二个1时,通过判断candidates[i]是否与candidates[i-1]相等 && used[i-1]是否为false,如果相等并且used[i-1]=false说明当前这个和前者相同的元素已经遍历完了所有它的可能值,不要再循环了。但是如果我们将数组进行排序,并引入一个bool类型的used数组,这个数组的长度与数组相同,每个位置的false代表这个位置对应的元素已经使用过,如果是true说明这个元素正在使用。排序后的数组:[1,1,2,5,6,7,10]起到将相邻的元素放到一起的作用。
2024-11-24 10:14:16
1025
原创 day21|leetcode 669. 修剪二叉搜索树, 108.将有序数组转换为二叉搜索树 ,538.把二叉搜索树转换为累加树
看到这道题,最先闪过的想法是:总不能从第一个开始遍历吧,那时间复杂度也太大了,能不能反着遍历,从最大值开始遍历二叉搜索树,因为最大值结点不变,次大值结点的新值就是最大值结点,然后边遍历树边递增,就可以一遍遍历就完成树的修改。目前为止刷算法的收获:虽然还是会碰到做过但是写不出代码的情况,但是明显感觉到思维被培养起来了,比如看到今天的题目,脑子里会瞬间闪过解决思路,印证答案的时候,竟然真的是我的思路!树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点。
2024-11-19 20:47:09
287
原创 day20|leetcode 235.二叉搜索树的最近公共祖先,701.二叉搜索树的插入操作,450.删除二叉搜索树中的结点
中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(有一个结论:从上往下遍历二叉搜索树,直到遇到值在[p,q]之间的cur节点,那么cur就是p,q的最近公共祖先。如上图,假设[p,q]=[1,9],5就是第一个值在[p,q]内的节点,那么5就是p,q的最近公共祖先。,将值插入二叉搜索树。若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
2024-11-19 19:07:23
536
原创 day18|leetcode 530.二叉搜索树的最小绝对差,501.二叉搜索树中的众数,236. 二叉树的最近公共祖先
能不能用前序遍历(中左右),结合回溯来求解,因为感觉回溯的弹进弹出很适合用来做root->val - root->left->val 和root->val-root->right->val谁是更小的值的比较,但是我没尝试这样做。在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。这个题是二叉搜索树,其实用数组也可以,把二叉搜索树存成递增数组,相邻节点的差值一定是最小的。二叉搜索树的中序遍历是有序的!
2024-11-16 14:39:27
827
原创 day17|leetcode 654最大二叉树,617合并二叉树,700,二叉搜索树中的搜索,98.验证二叉树
示例中:nums = [3,2,1,6,0,5],6是root,3是左子树的root,2是3的右孩子,因为2在3的右边。若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;注意:根节点左边的就是左子树,右边的就是右子树。它的左、右子树也分别为二叉搜索树。它的左、右子树也分别为二叉搜索树。给定一个不重复的整数数组。
2024-11-16 10:22:35
340
原创 day16|leetcode 112.路径总和,106.从中序与后序遍历序列构造二叉树
一旦切割完中序数组后,由于中序数组的左区间和后序数组一样,那么就可以划分出后序数组的左区间,显然后序数组的右区间就是除去最后一个根节点元素和左区间之后的所有元素。因为通过后序数组的最后一个元素,可以轻易在中序数组中找到这个元素的位置然后进行左右区间划分,但是后序数组难找到明确的划分位置。(3)如果要搜索其中一条符合条件的路径,那么递归一定需要返回值,因为遇到符合条件的路径了就要及时返回。(2)然后把中序数组分割为中序左数组和中序右数组(一定是先切割中序数组)(3)再把后序数组切割成后序左数组和后序右数组。
2024-11-16 08:09:32
923
原创 补day9|KMP!
0 && len %(len-(next[len-1]))==0)可以判断字符串由重复子串构成?摘录评论区的一句话“一个人能能走的多远不在于他在顺境时能走的多快,而在于他在逆境时多久能找到曾经的自己。给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。看上面那个链接的视频讲解kmp算法的过程,天哪,看了两遍,通透了。字符串的第一个匹配项的下标(下标从 0 开始)。(1)偶数长度:a b a b a b。(2)奇数长度:a a a a a。(3)不满足条件:a b a。如 ab ab ab。
2024-11-13 19:42:43
357
原创 day15|leetcode 110.平衡二叉树,257.二叉树的所有路径,404,左叶子之和,513.找树左下角的值,222.完全二叉树的节点个数
的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。思路:联想到上文的求二叉树的最大深度的题,可以用同样的逻辑,利用求最大深度的代码求出左右子树高度后相减,如果差大于1就不是平衡二叉树,直接返回-1。递归法:这题也用到了回溯,做了几个回溯题有一种感觉:如果一个二叉树的题,不仅要查根节点的左节点还要查根节点的右节点,就用回溯法。**理由:左叶子是:结点A的左孩子不为空,左孩子的左右结点为空,那么A的左孩子就是叶子节点。
2024-11-13 16:17:38
416
原创 day14|LeetCode226.翻转二叉树,101.对称二叉树,104.二叉树的最大深度,111.二叉树的最小深度
这里用前后序遍历都可以,但是用中序遍历会导致只翻转了左子树,因为中序遍历是左中右,反转一次:左子树(1)的两个子树反转,然后反转根节点,左子树(1)到右边,然后又反转左子树(1)的左右子树,这样的反转显然不是我们想要的。这样就算对称,本题使用递归+后序遍历(左右中),递归就想象成一个根节点,带两个子树,根节点不用判断,只要判断左右子树是否对称,在根节点处理结果返回即可,类似左右中的特性。对称二叉树即判断根节点的左右子树是否对称,左子树的左节点 = 右子树的右节点 , 左子树的右节点 = 右子树的左节点。
2024-11-12 21:18:19
278
原创 day13|LeetCode 144二叉树的前序遍历,145.后序遍历,94.中序遍历,102.层序遍历
后序遍历的顺序是左右中,可以通过:前序遍历:中左右---->中右左---->reverse--->左右中,即把前序遍历的左右顺序交换,再把结果反转就可以得到后序遍历。前后序遍历都可以理解为先访问中心节点,处理中心节点,访问中心节点的子节点,处理子节点,访问顺序与处理顺序一致。但是中序遍历(左中右)要先从根节点一路向下访问到左树最左下,然后开始处理结点,即访问顺序和处理顺序不一致。迭代法与递归法的区别就是用到栈,中间的根节点还是没影响,进中出中,左右的进出栈与递归不一样。
2024-11-12 21:14:47
295
原创 Day11|leetCode 150,逆波兰表达式,239.滑动窗口最大值,347.前k个高频元素
思路:滑动窗口的逻辑与队列先进先出的特性非常相近,这道题使用单调队列,即一旦新加入的元素比队列已经存储的元素大,就把已有元素挨个比对弹出,因为我们要的是最大值,小于入队元素的元素并不需要维护,让队列第一个元素始终为当前窗口的最大值,这样就可以用que.front()访问。当我们没有自定义的pop函数,如果下一次入队元素值小于刚刚滑出窗口的最大值,但是由于没有pop()将刚刚滑出窗口的元素值与旧的队首元素对比,删去旧的最大值元素,所以导致再次获取的队首仍然是旧的最大值元素/滑动窗口每次只向右移动一位。
2024-11-09 23:18:50
883
原创 day10|栈与队列
由于栈后进先出的顺序,一个栈不可能实现队列的先进先出特性,所以要借用一个辅助栈总共需要:(1)入队栈:把入队元素全部存起来(2)出队栈:把入队栈的全部元素依次弹出存入出队栈,再由出队栈依次弹出就可以得到“先进先出”的队列。
2024-11-08 17:25:36
218
原创 Day7:继续哈希!
但是如果是对比nums[i]==nums[i-1]此时i前方没有出现过-1,结果{-1,-1,2}被收录,i++,又抵达-1,此时由于前方出现过-1,continue跳过,重复结果不被计入。由于每个三元组不得重复,所以,{-1,-1,2}只能出现一次,但是当-1 -1 -1 -1 2 或者 -1 -1 2。i left right 如果对比nums[i]==nums[i+1]执行continue则会跳过{-1,-1,2}这个结果集,导致少了结果。
2024-11-05 22:50:49
720
原创 day6:哈希表!
数组:数据范围小用数组set:范围大用setmap : key有对应value用map题目:给出两个有小写字母组成的字符串s和t,判断是否t是s的字母异位词例子:s="anagram" t ="nagaram" return true;要求:返回交集同时去除重复元素元素数量大就用set解决**使用unordered_set实现自动去重 **set的几个常用函数以及用法:insert():向集合中添加元素,重复元素不会添加。。
2024-11-04 17:59:06
340
原创 周日打卡:平衡二叉树
定义:任意左右子树的高度差(从根节点到叶子节点的层数)不超过1后序遍历(层层向上返回计数,用于算高度)前序遍历(层层向下,用于算深度)
2024-11-03 20:31:14
131
原创 Day4|LeeTcode 链表专题
fast和slow同时指向虚拟头结点,让fast先走n+1个结点,然后fast和slow再一起走,直到fast为NULL,此时slow与fast之间相隔(n+1)个结点,(不理解就动手画画图!)这样slow就指向了要删除的结点的前一个!然后就可以简单地改变slow的指针域进行删除操作了!建议看代码随想录的这一节的视频,笔记画得有点丑,我就不放了qwq。这道题主要要注意保存第一个和第三个结点,防止丢失!
2024-11-02 21:11:35
261
原创 Day3|LeetCode 203移除链表元素,206反转链表,707设计链表
代码很简单,就是要记得增加一个临时指针temp用于找到后继结点,不然就会出现刚反转一个结点就找不到下一个结点了。
2024-11-01 20:45:19
210
原创 算法训练DAY2:LeetCode 209长度最小的子数组,59 螺旋矩阵,卡码网58区间和,44开发商买土地
让快指针先一直循环加下去,直到sum大于target的时候停下来,这时slow慢指针出动,一个一个减去sum[slow]直到sum再次小于target,fast再继续循环,最终就能获得最小的sublength。以3*3矩阵为例,当j=1时, 进入下一次判断,j=1满足j>starty(此时为0)的条件,j--变成0,填入7。然后模拟转一圈,思考需要哪些变量支撑:偏移量(用于让圈圈往内走),起始位置(用于定位,进行转圈操作)用前缀和解决:用数组vec记录元素值,数组pre记录一个又一个区间的值。
2024-10-31 21:43:02
206
原创 代码随想录训练营第一天|LeetCode704二分查找,27移除元素,977.有序数组的平方
使用左右两个指针指向数组的左右边界,因为元素可能存在负数,所以最大平方一定在左侧或者右侧,故利用两个指针指向元素的平方的大小比较,将较大的那个填入新数组的最右端,从右往左放元素。可以使用暴力解法,先全部平方,再排序,时间复杂度为O(n+nlogn)两个方法,二者的区别主要在于右边界以及是否应该将左右边界相等放入循环。对于取边界这个问题我能理解了,但是我一开始不理解为什么要用。注意:原地删除,即把删去这个元素后,后面的元素值前移。时间复杂度:O(n^2)时间复杂度:O(n)时间复杂度:O(n)
2024-10-30 20:45:59
284
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人