- 博客(28)
- 收藏
- 关注
原创 代码随想录算法训练营第32天 | LeetCode122.买卖股票的最佳时机II、LeetCode55.跳跃游戏、LeetCode45.跳跃游戏II
本题有一个很巧妙的思路,我们可以每天买当天股票,第二天卖出,再买入当天的股票,计算每天的利润。重复上述步骤,就可以将一个利润分解看。刚开始看见本题,很懵,数组的元素表示对应位置可以跳的最大步数,那么到底该跳几步呢,有那么多值可以选?本题跳跃游戏II 和 跳跃游戏的区别在于,本题要是一定可以到达数组终点,要求我们输出最少的跳跃次数。思路虽然是这样的,但是在写代码的时候还不能真的能跳多远就跳多远,那样就不知道下一步最远能跳到哪里了。局部最优:当前可移动距离及可能多走,如果还没到终点,步数再加一个。
2023-04-15 21:27:41
272
原创 代码随想录算法训练营第31天 | LeetCode455.分发饼干、LeetCode376.摆动序列、LeetCode53.最大子序和
本题的题目的核心就是一句话:你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。为了满足更多的小孩,就要避免不必要的浪费,那么就是说我们要尽可能满足胃口大的孩子,让胃口大的孩子尽可能多的满足,达到局部最优解,那么在整个逻辑中就是全局最优解。我们可以将摆动序列抽象成一个个小山峰,那么按照题目的意思我们只要获取出由数组抽象出的山峰中有。本题要求我们输出给定数组中的最长摆动序列的长度。本题的求的是连续的子数组(连续!局部最优:当前“连续和”为负数的时候,立即抛弃,从下一个值开始重新计算“连续和”。
2023-04-14 20:44:12
243
原创 代码随想录算法训练营第29天 | LeetCode491.递增子序列、LeetCode46.全排列、LeetCode47.全排列II
其实收集子序列也是收集子集的一种,在收集子集时,我们是把抽象树中的所有节点都进行存放,不进行添加返回值,本题就是多加一个限制条件。我们在向path中添加元素的时候,其实每一次递归开始都是从i = 0开始的,在遍历整个数组的时候,那么怎么才能在已经在path中的元素不会被重复添加呢?本题是排列问题,是有序的,[1 , 2]和[2 , 1]在结果中是不一样的排序,不需要startindex来记录递归中的位置。在单层递归逻辑中,使用过的元素是不能重复使用的,在整个递归逻辑中也就是path中是可以出现重复的元素。
2023-04-12 21:44:51
245
原创 代码随想录算法训练营第28天 | LeetCode93.复原IP地址、LeetCode78.子集、LeetCode90.子集II
本题的难点:如何模拟切割的操作、如何找到切割点、判断子串是否是合法的IP地址、如何将合法的子串拼接。本题和LeetCode78.子集的区别是,本题所给定的整数数组nums中的元素可以重复,并且我们输出到结果集中的单个集合不能重复。因为本题是收集树中的所有节点,我们每一次递归都要收集。之前的组合问题,其实都是收集抽象树中的叶子节点,那本题是要求我们返回所有的子集,就是找抽象树的所有节点。,此时就需要我们控制添加次数,当我们添加三次后,直接判断剩余的字符是否符合正确的IP地址的格式。
2023-04-11 22:04:28
240
原创 代码随想录算法训练营第27天 | LeetCode40.组合总和II、LeetCode131.分割回文串
本题 组合总和II 它的给定集合candidates中的元素允许重复出现,但是在递归的过程中不允许重复使用,那也就是说我们这道题目涉及到了元素的去重。当我们的切割线的位置大于等于字符串的长度时,就是将整个字符串切割过一遍,也就到了递归终点,本题的判断分割后的字符串是否是回文串的操作是在单层递归中做的。本题有以下几个难点:1.切割问题可以抽象为组合问题 2.如何模拟那些切割线 3.切割问题中递归如何终止 4.在递归循环中如何截取子串。给定集合中有重复的元素,但是在结果集中不能出现重复的组合。
2023-04-10 22:01:19
117
原创 代码随想录算法训练营第25天 | LeetCode216.组合总和III、LeetCode17.电话号码的字母组合
本题中索引传进来的参数为index,那为什么不和之前一样传入一个startindex,来记录下一次递归的位置呢?本题和之前组合 和 组合III不同的是 本题操作数组并不是在同一个数组中,并不需要去重,记录我们下一次的位置。我们依旧吧result 和 path 定义成全局变量,当然 我们也可以将累加和sum 也定义为全局变量,不过创建一个新的对象的过程,会加大内存运行时间,不过也没有什么关系。我们知道,有递归就有回溯,回溯是递归的附加物;在递归的代码中不一定看见回溯的身影,但是一定有回溯的思想出现。
2023-04-08 21:50:16
478
原创 代码随想录算法训练营第24天 | LeetCode77.组合
如图,为什么要进行剪枝操作:当我们n = 4, k = 4的时候,进行第一层for循环后,取2操作已经没有意义了,因为组合中的无序性,在取2的时候元素中不可能出现元素1,那集合的长度也不可能符合题目要求k = 4。首先组合问题要先搞清楚什么是组合,组合是元素无序的存放到集合中,和排列不一样,排列是有序的。如果k比较少的情况,我们可以直接for循环进行嵌套,那么如果k比较大,那么我们就要嵌套k层for循环,这想想也是不现实的。我们的递归逻辑是表示二叉树的深度,单层的递归逻辑就是二叉树的宽度(横向)。
2023-04-07 20:49:47
486
原创 代码随想录算法训练营第23天 | LeetCode.669.修建二叉搜索树、LeetCode.108.将有序数组转化为二叉搜索树、LeetCode.538.把二叉搜索树转换为累加树
它是一个二叉搜索树,二叉搜索树的中序遍历是一个单调递增的数组,那么在一个数组中逆向求累加,问题是不是简单很多。在二叉搜索树中,结点的右子树都大于该节点,然而[1,3]中 不符和条件的结点0,它的右子树我们并没有进行考虑 ,它的右子树中的结点有可能满足。改题目也是修改二叉树结构的题目,但是它和删除二叉搜索树的结点不同,删除二叉搜索树结点是只删除一个目标结点即可,本题是删除不在范围内的所有结点。这不是我们希望看到的。我们只需要在删除该结点时,再递归它的右子树,重复之前操作,将符合条件的结点向上返回就可以了。
2023-04-06 11:59:58
79
原创 代码随想录算法训练营第22天 | LeetCode.235.二叉搜索树的最近公共祖先、LeetCode.701.二叉搜索树中的插入操作、LeetCode.450删除二叉搜索树中的节点
和上一题的添加结点不同,上一题的添加结点操作都是在叶子结点上,我们不需要更改原本二叉树的结构。因为是有序树,所以 如果 中间结点 是 q 和 p的公共祖先,那么中结点的数组一定在[p,q]区间。本题是在二叉搜索树中进行插入,且二叉搜索树又是有序的。由上图可以看出,第一个在[p,q]或者[q,p]区间中结点 一定是最近结点,如果再向下遍历 要么p结点不在范围内,要么q结点不在范围内。那么只要从上到下遍历,遇到的结点数值在[p,q]或者[q,p]区间中 则一定可以说明该结点就是q和p的公共祖先。
2023-04-05 17:57:56
89
原创 代码随想录算法训练营第21天 | LeetCode.530.二叉树的最小绝对差、LeetCode.501.二叉树中的众数、LeetCode.236.二叉树的最近公共祖先
这是一个二叉搜索树,也就是说是一个有序树,之前我们在遍历一个二叉搜索树的时候,用到的遍历顺序都是中序遍历,因为中序遍历相当于遍历出一个单调递增的数组,这样原本复杂的问题就变得简单多了。并且后序遍历的过程就是天然的回溯过程,根据左右子数的返回值,来处理中结点的逻辑。上述定义说明了重新定义的二叉搜索树中可以包含重复值,本题虽然改变了一点定义但是二叉搜索树的大题特征还是没有改变,也就是说我们还是可以用中序遍历,遍历出一个数组,数组的整体是递增的。本题的难点是如何找到出现最多结点的次数,并返回这个结点的值。
2023-04-04 22:02:19
108
原创 代码随想录算法训练营第20天 | LeetCode.654.最大二叉树、LeetCode.617.合并二叉树、LeetCode.700.二叉搜索树中 的搜索、LeetCode.98.验证二叉搜索树
根据题目要求,也就是说,这个数组的最大元素会在根节点上,难点就是如何找到这个在这个数组中找到这个最大值,然后将他变为二叉树的根节点,在根据这个结点将数组分割为左右两个数组进行下一层的递归。根据它的定义,我们知道搜索二叉树是有序的,这样我们相当于在二叉树中搜索一个结点。①若它的左子树不空,则左子树上所有结点的值均小于它的根节点的值。②若它的右子树不空,则右子树上所有结点的值均小于它的根节点的值。那么什么是二叉搜索树。本题是利用二叉搜索树的特性解题,是一个非常好的例子。②结点的右子树只包含大于当前结点的树。
2023-04-03 21:57:07
86
原创 代码随想录算法训练营第19天 | LeetCode.513.找树左下角的值、LeetCode.112.113.路径总和II、III、LeetCode.106.从中序与后序遍历构造二叉树
参数需要TreeNode root,int result(记录叶子结点的值), int depth(因为和层序遍历不同,递归法并不知道到自己当前处于第几层,所以需要一个遍历进行记录对比)注意点:从后序数组中找到的切割点,一定要先切中序数组,因为中序数组的遍历顺序是左--中--右,找到的这个切割点就是中,它把左右子数清晰的分开,这样才能进行下一次切割。当已知一个二叉树的中序遍历和后序遍历就可以确定唯一一个二叉树,因为中序遍历可以将二叉树的左右孩子分开,后序遍历可以直到每个左右孩子的双亲结点。
2023-04-02 21:45:57
95
原创 代码随想录算法训练营第17天 | LeetCode.110.平衡二叉树、LeetCode.257.二叉树的所有路径、LeetCode.404.左叶子之和
本题用的是后序遍历,因为判断一个树是否是平衡二叉树是判断它左右子树的。题目的要求也是从根节点到叶子的路径,故该题的二叉树遍历顺序是前序遍历,这样方便让父节点指向孩子结点,找到对应的路径。首先,要满足题目判断一个数是否是平衡二叉树,要先了解什么是平衡二叉树。本题用到了 回溯的思想,因为我们要把路径记录下来,需要回溯来回退到一个路径进入到另一个路径。首先要注意是判断左叶子,不是二叉树的左侧节点,要层序遍历是要进行条件筛选的。我们进行层序遍历的时候,一定要明确,是左叶子,条件不要加到右叶子上。
2023-03-31 22:19:23
94
原创 代码随想录算法训练营 | 第16天 LeetCode.104.二叉树的最大深度、LeetCode.111.二叉树的最小深度、LeetCode.222.完全二叉树的节点个数
理清概念,最小深度是根节点到叶子节点的最小举例,而叶子节点是左右孩子都要为空。二叉树节点的深度:指从根节点到该节点的最长简单路径的条数或者节点数(取决于深度从0开始还是从1开始)二叉树节点的高度:指从该节点到叶子节点的最长简单路径的条数后者节点数(取决于高度从0开始还是从1开始。本题可以使用前序(中左右),也可以使用后序遍历(左右中),使用前序遍历求的是深度,后序求的是高度。此时和求解二叉树的最大深度思路完全相同,在每次遍历左孩子或者右孩子的时候,都进行计数。而根节点的高度就是二叉树的最大深度。
2023-03-30 22:11:21
79
原创 代码随想录算法训练营第15天 | LeetCode.102.二叉树的层序遍历、LeetCode.226.反转二叉树、LeetCode.101.对称二叉树
我们发现前序遍历和后序遍历的模板是一样的,只是调换一下节点、左子树、右子树顺序,那么中序遍历是不是这样呢?但是中序遍历的遍历规则是左子树--节点--右子树 ,我们在处理完第一个左子树时,进入递归,进行左右子树的交换,此时,上一层的左子树,变成了这一层的右子树,也就是说,要实现交换,我们还要继续操作左子树。上图很形象的画出,当我们遍历这层的节点时,先记录当前的队列的长度,这个长度也就是这一层的节点个数,如果当前节点有左右孩子,就将这个它的左右孩子添加到栈中。层序遍历和前中后序的遍历没有什么关系。
2023-03-29 22:17:18
91
原创 代码随想录算法训练营第14天 | 二叉树遍历的递归算法
那么继续进入递归中,此时的root = null 进入条件判断语句,此时满足条件执行return操作,该方法也在栈内存中弹栈,此时B节点的左右孩子都遍历完成,那么B节点也在栈内存中弹栈,此时的栈内存中,只有A节点,那么继续执行A节点的语句,此时判断A节点的整个右子树.......(和上述操作相同)当A节点的右子树全部遍历完,此时A节点的语句也全部执行完,在栈内存中也弹栈处理,最后返回结果的集合。之后判断递归条件,判断当前的节点是否等于NULL,如果不为空跳出当前的判断语句,将当前的节点添加到列表中,到。
2023-03-28 23:01:23
206
原创 代码随想录算法训练营第13天 | LeetCode239.滑动窗口最大值
根据这个动画可以很形象的看出,当我们插入元素时,如果插入元素(val)大于当前队列中的元素(deque.peek())将之前的元素全部poll出去,也就是说val是队列现在的最大值,且在当前队列的出口;这种题目一拿到手就应该想到暴力算法行不通,因为滑动窗口的时间复杂度就是O(n)了,而且要比较出滑动窗口内的最大值,就和滑动窗口的大小k有关,那暴力算法的时间复杂度就是O(kn),且k的取值可以取到很大,这样暴力算法一定会超时。(可以创建一个双端队列,队列的两端都可以进行出队和入队的操作)
2023-03-27 21:52:44
102
原创 代码随想录算法训练营第11天 | LeetCode.20.有效括号、LeetCode.1047.删除字符串中的所有相邻重复项、LeetCode.150.逆波兰表达式
①栈为空的情况下不需要比较,直接添加到栈中②第二个元素添加时,栈不为空,先与栈顶元素比较,是否是值相同的元素,结果不是值相同的元素,添加到栈中③第三个元素添加时,栈不为空,先与栈顶元素比较,结果是值相同的元素,此时在字符串中的字符并不添加到栈中,并把栈顶的元素进行弹栈处理。在日常生活中,我们接触到的都是中缀表达式例如:1+2;用栈来解决这个问题,把字符串按序取出,如果是左括号,那就在栈中添加一个相应的右括号,如果是右括号,就和栈顶元素进行比较,如果相等就把栈中元素进行弹栈操作,不相等就直接退出。
2023-03-25 22:28:51
106
原创 代码随想录算法训练营第10天 | LeetCode.232.用栈实现队列、LeetCode.225.用队列实现栈
题目给出要求:请你仅使用两个栈实现先入先出队列。队列是先入先出的线性表,栈是后入先出的线性表。我们用一个栈模拟队列的进栈过程,利用栈后入先出的原则,刚刚在栈顶的元素就被取出放入另一个栈的栈底。从这个栈中取出元素,模拟了队列的出栈过程。上面代码中pop()和peek()方法中,反复写了相同的代码,将stIn中的元素出栈再存入stOut。可以写一个方法 包含 这个过程,在需要的时候调用,避免代码的重复。
2023-03-24 21:13:33
151
原创 代码随想录算法训练营第7天 | 剑指 Offer 05. 替换空格、剑指 Offer 58 - II. 左旋转字符串
代码随想录算法训练营第7天 | 剑指 Offer 05. 替换空格、剑指 Offer 58 - II. 左旋转字符串
2023-03-22 22:15:42
105
原创 代码随想录算法训练营第7天 | LeetCode.344.反转字符串、LeetCode.541.反转字符串II 、LeetCode.151.反转字符串中的单词
代码随想录算法训练营第7天 | LeetCode.344.反转字符串、LeetCode.541.反转字符串II 、LeetCode.151.反转字符串中的单词
2023-03-22 21:40:33
124
原创 代码随想录算法训练营第6天 | LeetCode.454.四数相加、LeetCode.383.赎金信、LeetCode.15.三数之和、LeetCode.18.四数相加
代码随想录算法训练营第6天 | LeetCode.454.四数相加、LeetCode.383.赎金信、LeetCode.15.三数之和、LeetCode.18.四数相加
2023-03-21 21:58:14
191
原创 代码随想录算法训练营第5天 | LeetCode.242.有效的分母异位词、LeetCode.349.两个数组的交际、LeetCode.202.快乐数、LeetCode.1.两数之和
当target = 9时,我们遍历到集合中第一个元素2时,我们可以查找之前遍历过的集合中有没有 和2相加 等于 目标target = 9的元素。按照上述思路,我们需要用一个集合存放之前遍历过的元素,一个用于存放当前的索引。不满足题目的要求,这时我们刚好可以用map集合(key - value)以键值对的形式存储数据,且可以快速查找目标key是否存在map集合中。根据题目要求 核心是:输出结果中的每个元素一定是惟一的。解决第二个难点,寻找重复出现的数,我们想要数组不出现重复数,可以使用set集合帮助去重。
2023-03-21 00:00:08
309
原创 代码随想录算法训练营第4天 | LeetCode24.两两交换链表中的节点、LeetCode19.删除链表的倒数第N个节点、面试题02.07.链表相交、LeetCode142.环形链表II
代码随想录算法训练营第4天 | LeetCode24.两两交换链表中的节点、LeetCode19.删除链表的倒数第N个节点、面试题02.07.链表相交、LeetCode142.环形链表II
2023-03-19 21:12:06
62
原创 代码随想录算法训练营第3天 | LeetCode203.移除链表元素、LeetCode707.设计链表、LeetCode206反转链表
代码随想录算法训练营第3天 | LeetCode203.移除链表元素、LeetCode707.设计链表、LeetCode206反转链表
2023-03-17 22:39:56
356
原创 代码随想录算法训练营第2天 | LeetCode977.有序数组的平方、LeetCode209.长度最小的子数组、LeetCode59.螺旋矩阵II
代码随想录算法训练营第2天 | LeetCode977.有序数组的平方、LeetCode209.长度最小的子数组、LeetCode59.螺旋矩阵II
2023-03-16 17:49:01
515
原创 代码随想录算法训练营第1天| LeetCode704 二分查找、LeetCode27移除元素
代码随想录算法训练营第1天| LeetCode704 二分查找、LeetCode27移除元素
2023-03-15 13:22:13
767
2
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅