自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 代码随想录算法训练营第三十六天| 435. 无重叠区间、763.划分字母区间、56. 合并区间

此时问题就是要求非交叉区间的最大个数。这里记录非交叉区间的个数还是有技巧的,如图:区间,1,2,3,4,5,6都按照右边界排好序。当确定区间 1 和 区间2 重叠后,如何确定是否与 区间3 也重贴呢?就是取 区间1 和 区间2 右边界的最小值,因为这个最小值之前的部分一定是 区间1 和区间2 的重合部分,如果这个最小值也触达到区间3,那么说明 区间 1,2,3都是重合的。接下来就是找大于区间1结束位置的区间,是从区间4开始。

2023-03-22 21:59:30 99

原创 代码随想录算法训练营第三十五天| 860.柠檬水找零、 406.根据身高重建队列、 452. 用最少数量的箭引爆气球

但仔细思考一下就发现:如果把气球排序之后,从前到后遍历气球,被射过的气球仅仅跳过就行了,没有必要让气球数组remove气球,只要记录一下箭的数量就可以了。直觉上来看,貌似只射重叠最多的气球,用的弓箭一定最少,那么有没有当前重叠了三个气球,我射两个,留下一个和后面的一起射这样弓箭用的更少的情况呢?可以看出首先第一组重叠气球,一定是需要一个箭,气球3,的左边界大于了 第一组重叠气球的最小右边界,所以再需要一支箭来射气球3了。既然按照起始位置排序,那么就从前向后遍历气球数组,靠左尽可能让气球重复。

2023-03-22 21:56:30 92

原创 代码随想录算法训练营第三十四天| 1005.K次取反后最大化的数组和、 134. 加油站、135. 分发糖果

如果 ratings[i] > ratings[i + 1],此时candyVec[i](第i个小孩的糖果数量)就有两个选择了,一个是candyVec[i + 1] + 1(从右边这个加1得到的糖果数量),一个是candyVec[i](之前比较右孩子大于左孩子得到的糖果数量)。如果ratings[i] > ratings[i - 1] 那么[i]的糖 一定要比[i - 1]的糖多一个,所以贪心:candyVec[i] = candyVec[i - 1] + 1。

2023-03-22 21:22:17 104

原创 代码随想录算法训练营第三十二天| 122.买卖股票的最佳时机II、55. 跳跃游戏、45.跳跃游戏II

局部最优推出全局最优,找不出反例,试试贪心!如图:i每次移动只能在cover的范围内移动,每移动一个元素,cover得到该元素数值(新的覆盖范围)的补充,让i继续移动下去。而cover每次只取 max(该元素数值补充后的范围, cover本身范围)。如果cover大于等于了终点下标,直接return true就可以了。

2023-03-20 23:25:35 88

原创 代码随想录算法训练营第三十一天| 455.分发饼干、376. 摆动序列、53. 最大子序和

解题思路:为了满足更多的小孩,就不要造成饼干尺寸的浪费。大尺寸的饼干既可以满足胃口大的孩子也可以满足胃口小的孩子,那么就应该优先满足胃口大的。。可以尝试使用贪心策略,先将饼干数组和小孩数组排序。然后从后向前遍历小孩数组,用大饼干优先满足胃口大的,并统计满足小孩数量。

2023-03-20 23:17:07 190

原创 代码随想录算法训练营第二十九天| 491.递增子序列、46.全排列、47.全排列 II

确定单层递归逻辑,由于结果中的子集要求是递增的,因此在for循环遍历中需要判断当前遍历的元素是大于或等于path中最后一个元素的。同时,因为在树枝中不能取同一元素,因此需要添加一个标记数组used用来记录已经用过的元素,当出现上述两种情况时则跳到下一层循环。确定单层递归逻辑,当used[ i ] 为true时,跳到下一循环,若没有用过,添加该元素到path中,将used[ i ] 改为true,进入到下一层递归,注意used和路径数组path的回溯。确定递归函数参数,传入数组nums以及标记数组used。

2023-03-15 23:20:38 70

原创 代码随想录算法训练营第二十八天| 93.复原IP地址、 78.子集、90.子集II

确定单层递归逻辑,for循环遍历字符串s,判断s到startIndex之间的子字符串是否符合标准,若不符合直接break退出循环,若符合,在字符串s的切割符处添加逗点,pointNum++,进入到下一次递归,注意传入的startIndex的应该为startIndex+2,因为加了一个逗点。确定单层递归逻辑,用for循环遍历数组,将每个元素添加到路径集path中,继续递归,需要注意本题添加路径到结果集的操作可以写到递归函数开头,这样可以保证每个节点都能够获取到。本题比较简单,其实就是。

2023-03-15 00:17:37 28

原创 代码随想录算法训练营第二十七天| 39. 组合总和、40.组合总和II、131.分割回文串

因为不能使用到同一个元素,所以需要一个标记数组used来判断该元素是否被用过,在进入递归函数前需要将数组进行排序,通过该数组来避免两个相同值的不同元素在同一层递归逻辑中重复使用,注意在candidates[ i ] == candidates[ i - 1 ] 还需要额外判断candidates[ i - 1 ] 是否为false,如果不加这个条件的话结果一定会少,因为这影响到了向下递归时候出现的重复值,没有将该值添加到path路径中。确定终止条件,当sum值等于或者超过target值的时候结束递归。

2023-03-14 23:54:07 28

原创 代码随想录算法训练营第二十五天| 216.组合总和III、17.电话号码的字母组合

图中可以看出遍历的深度,就是输入"23"的长度,而叶子节点就是我们要收集的结果,输出["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]。解题思路:本质上和77组合是一样的,只是多了一个数字相加要等于目标值的限制,以及集合的范围为1~9,写法和77基本是一样的,注意回溯问题。然后for循环来处理这个字符集,注意回溯。首先需要建立一个String类型的数组,总共元素为10个,下标刚好定位每个数字对应的字符串,如2对应"abc"。

2023-03-12 23:10:16 94

原创 代码随想录算法训练营第二十四天| 77. 组合

来举一个例子,n = 4,k = 4的话,那么第一层for循环的时候,从元素2开始的遍历都没有意义了。第一次取1,集合变为2,3,4 ,因为k为2,我们只需要再取一个数就可以了,分别取2,3,4,得到集合[1,2] [1,3] [1,4],以此类推。图中每一个节点(图中为矩形),就代表本层的一个for循环,那么每一层的for循环从第二个数开始遍历的话,都没有意义,都是无效遍历。可以看出这棵树,一开始集合是 1,2,3,4, 从左向右取数,取过的数,不再重复取。这个遍历的范围是可以剪枝优化的,怎么优化呢?

2023-03-10 22:54:51 57

原创 代码随想录算法训练营第二十三天| 669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树

解题思路:本体可以看到数组从后往前是依次累加递增的,所以我们可以采用右中左的遍历方式来来遍历这个二叉树,需要用到两个指针,一个指向节点,一个指向节点的上一个节点pre=0,每次节点node+=pre,然后pre=node获取当前节点的值,当遇到空节点的时候即终止。解题思路:确定数组的中间节点作为根节点,左子树为更节点左边数组,右子树为右边的右边数组,当数组为0时返回null,当数组大小为1时则返回一个新的节点,值为这个数组的值。注意数组的切割,这里用的是左闭右开的写法。

2023-03-09 21:39:11 27

原创 代码随想录算法训练营第二十二天| 235. 二叉搜索树的最近公共祖先、 701.二叉搜索树中的插入操作、450.删除二叉搜索树中的节点

第五种情况比较复杂,需要改变二叉搜索树的结构,这里有两种处理方法,一种是找到该节点右子树最小的值,然后将该最小节点的左子树指向原节点的左子树,最后返回原节点的右子树即可。与普通二叉树求最近公共祖先方法类似,不过可以利用二叉搜索树的特性队算法进行剪枝操作,当节点大于两个值p和q时,返回左子树的结果,当小于两个值时返回右子树的结果。另一种方法也是同理,找到左子树最大的值,将该最大节点的右子树指向原节点的右子树,最后返回原节点的左子树。3、节点左孩子为空,右孩子不为空,返回右孩子。5、节点左右孩子都不为空。

2023-03-09 21:19:22 33

原创 代码随想录算法训练营第二十一天| 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、 236. 二叉树的最近公共祖先

解题思路:利用后序遍历,当遇到节点为q或是p的时候返回该节点,若是遇到节点为空时返回空,然后当前节点接受左右子树的返回结果,总共四种情况,需要了解到的是,当p或q本身刚好是公共祖先的情况下,其实这种情况在最开始的判断上已经包含到了,即遇到p或q就返回该节点,最终根节点就会返回p或q节点作为结果。解题思路:和上题思路基本一样,用中序遍历,两个指针,一个作为pre初始值为null,一个作为当前节点,通过比较是否相同来去计算出现次数,若大于等于maxCount,来去更新数组。

2023-03-07 22:15:54 35

原创 代码随想录算法训练营第二十天| 654.最大二叉树、 617.合并二叉树、700.二叉搜索树中的搜索、 98.验证二叉搜索树

也是通过中序遍历,定义一个前序指针pre,初始值为null,来去存储节点值,通过比较pre和节点值的大小来去判断其是否符合搜索二叉树的特性。解题思路:本质上与105、利用中序后序遍历的数组构建二叉树的思路是一样的,通过找到数组的最大值作为切割点,左边部分为左子树,右边部分为右子树,再通过递归将最大二叉树给创建出来。解题思路:同时前序遍历两个二叉树,若第一个为空则返回第二个,若第二个为空同理,若都有值则将俩值相加,可通过覆盖将第一颗树作为合并二叉树,也可以创建一个新的二叉树作为合并二叉树。

2023-03-06 23:58:38 42

原创 代码随想录算法训练营第十八天| 513.找树左下角的值、 112. 路径总和 113.路径总和ii、106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树

首先回忆一下如何根据两个顺序构造一个唯一的二叉树,相信理论知识大家应该都清楚,就是以 后序数组的最后一个元素为切割点,先切中序数组,根据中序数组,反过来再切后序数组。可以使用前序遍历(当然中序,后序都可以,因为本题没有 中间节点的处理逻辑,只要左优先就行),保证优先左边搜索,然后记录深度最大的叶子节点,此时就是树的最后一行最左边的值。利用层序遍历,创建一个队列来存放二叉树的元素,而每次队列的第一个值即为该层最左边的元素,所以最后一层的队列第一个元素即为树左下角的值。说到一层一层切割,就应该想到了递归。

2023-03-05 17:01:26 29

原创 代码随想录算法训练营第十七天| 110.平衡二叉树、 257. 二叉树的所有路径、404.左叶子之和

因为是从下往上传递数值,因此最好采用后序遍历,同时要注意遍历到叶子节点的时候是不能记录该值的,因为我们不清楚该节点是否是左叶子,我们需要进行记录的是一个节点的左节点不为空,与此同时此节点的左右节点同为空的情况,将该左节点的值返回到上一层。每当遍历到一个节点时,需要将该节点添加到该路径数组中,如果该节点的左右节点都为空时,证明此节点即为叶子节点,此时需要将路径数组格式处理好后添加到结果数组中。需要理解题意的左叶子是什么意思,其实就是一个节点的左节点为叶子节点的时候,此时需要将其节点值返回到上层。

2023-03-03 23:58:44 46

原创 代码随想录算法训练营第十六天| 104.二叉树的最大深度、 111.二叉树的最小深度、 222.完全二叉树的节点个数

我来举一个典型的例子如题:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2^(h-1) 个节点。完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。对于情况一,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。

2023-03-03 23:34:56 27

原创 代码随想录算法训练营第十五天| 102层序遍历、226.翻转二叉树、101. 对称二叉树

通过递归的方法去解决问题,遍历选择后序遍历,因为要得到左右孩子的比较结果,最终传到中间的结点,因此选择这种遍历方式,因为是对称二叉树,因此比较的俩结点在外侧是左孩子的左孩子对比右孩子的右孩子,内侧则是左孩子的右孩子对比右孩子的左孩子,当两个布尔值的与运算结果返回给父节点。层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。这种遍历的方式和我们之前讲过的都不太一样。需要借用一个辅助数据结构即队列来实现,

2023-03-02 19:44:09 76

原创 代码随想录算法训练营第十四天| 144. 二叉树的前序遍历、94. 二叉树的中序遍历、145. 二叉树的后序遍历

解题思路:确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。

2023-02-28 22:43:12 53

原创 代码随想录算法训练营第十三天| 239. 滑动窗口最大值、347.前 K 个高频元素

解题思路:暴力方法,遍历一遍的过程中每次从窗口中再找到最大的数值,这样很明显是O(n × k)的算法。我们其实可以使用单调队列来完成这个滑动窗口的操作,定义这么一个单调队列,队列里面的元素是由大到小的,当要存入的元素队列的最后一个时,需要将最后一个元素移除,一直循环直到要存的元素最大或是最后一个元素比要存入的大,然后再将该元素存入到队列中,这样的话当需要获取该窗口的最大元素仅需要获取这个队列的peek()即可,因为队列头部存储的是这个队列最大的元素。

2023-02-27 23:46:41 33

原创 代码随想录算法训练营第十一天| 20. 有效的括号、1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值

解题思路:理解好逆波兰表达式是什么意思后其实就很好做题了,当遇到数字时存入栈中,当遇到符号就将栈中最上面两位数拿出来进行该符号的运算,最后栈中的元素即使最终结果。解题思路:用栈的思想来去解决,遍历字符串,当栈最顶层元素与遍历的元素相等时将该元素从栈中弹出,最后得到的栈即是没有相邻重复项的字符串,最后处理返回正序的字符串。第一种情况,字符串里左方向的括号多余了 ,所以不匹配。解题思路:用栈来去解决问题,需要处理好3种错误的情况。第三种情况,字符串里右方向的括号多余了,所以不匹配。

2023-02-26 21:33:13 41

原创 代码随想录算法训练营第十天| 232.用栈实现队列、225. 用队列实现栈

解题思路:栈的特点是先进后出,队列的特点是先进先出,所以要用栈实现队列的话, 需要准备两个栈,一个作为进的栈stackIn,一个作为出的栈stackOut,每当要存储一个新元素的时候,直接push就可以了,而当需要实现队列pop的时候,需要将stackIn的元素清空,若stackOut为空的时候,都存入到stackOut中,再去pop stackOut。实现队列peek的时候,也是用上述方法,最后去peek stackOut。

2023-02-24 22:31:00 33

原创 代码随想录算法训练营第八天| 344.反转字符串 、541. 反转字符串II、 剑指Offer 05.替换空格、 151.翻转字符串里的单词、 剑指Offer58-II.左旋转字符串

解法2:定义一个新字符串str来存储需要的空格数,遍历原字符串,当遇到空格时新字符串str+=(两个空格),遍历完成后原字符串s+=str,将其转化为数组,然后用双指针,第一个作为快指针指向原字符串的最后一位,第二个为慢指针指向新字符串的最后一位,然后两个指针移动来去更新整个数组的元素。解题思路:双指针法,一个指向字符串第一个元素,一个指向最后一个元素,定义一个temp来存储字符,调换两个元素值,然后同时向中间移动一格,直到left>=right。解题思路:这道题总共分三步。第二步是翻转整个字符串。

2023-02-22 21:46:32 64

原创 代码随想录算法训练营第七天| 454.四数相加II 、383. 赎金信、15. 三数之和、18. 四数之和

解题思路:双指针法,首先将数组进行排序,定义三个指针i,left,right,第一个指针固定,left=i+1,right=nums.length-1,当sum值大于0时,因为sum要等于0,所以right指针要左移,同理小于0时,left右移,当等于0时,将该arraylist集存储到结果集中。同样要注意不能出现重复结果,所以要判断i=i-1,j=j-1,left=left+1,right=right-1的情况。当排序后,若i已经大于0的时候,可以直接返回result来进行剪枝操作。

2023-02-21 20:39:53 106

原创 代码随想录算法训练营第六天| 242.有效的字母异位词、349. 两个数组的交集、 202. 快乐数 、 1. 两数之和

解题思路:其实是需要判断加起来的值sum是否出现重复,重复时即不是快乐数。需要建立一个哈希表,将每次sum的值存入哈希表中,循环计算sum的值,当sum值为1时,返回true,当sum存在于哈希表中返回false,否则将该sum值存入哈希表中,继续循环。建立一个哈希表用来存放遍历过的元素,key为数值,value为下标,遍历数组,遍历每个元素的时候,检查哈希表中的键值是否存在target-nums[i],若存在返回这两个值的下标,若不存在将该值及其下标存入哈希表中,遍历完成后若无则返回空数组。

2023-02-20 23:50:01 25

原创 代码随想录算法训练营第四天| 24. 两两交换链表中的节点 、 19.删除链表的倒数第N个节点、 面试题 02.07. 链表相交、 142.环形链表II

首先分别计算两个链表的长度,假设为lengthB和lengthA,lengthB和lengthA的差值为n,定义两个指针分别指向两个链表的头部,让长度长的链表先走n步,然后同时移动两个指针,如果指针相等时候返回其中一个指针即可,若无相等情况返回空。解法2:双指针:可以通过快慢指针来求解,快指针首先移动n步,然后快慢指针同时移动,当快指针的next指向空的时候,慢指针的下一个元素即为要删除的目标元素,此时将慢指针的next指向慢指针的next的next即可完成删除操作。通过两次遍历完成该题。

2023-02-19 17:54:06 55

原创 代码随想录算法训练营第三天| 203.移除链表元素 、 707.设计链表、206.反转链表 。

关键是初始化的地方,可能有的同学会不理解, 可以看到双指针法中初始化 cur = head,pre = NULL,在递归法中可以从如下代码看出初始化的逻辑也是一样的,只不过写法变了。解题思路:设置一个虚拟头结点来进行删除操作,遍历链表,当指针的next为目标元素时,将指针的next指向指针next的next,从而完成删除操作。为什么要保存一下这个节点呢,因为接下来要改变 cur->next 的指向了,将cur->next 指向pre ,此时已经反转了第一个节点了。具体可以看代码(已经详细注释),

2023-02-19 17:06:32 34

原创 代码随想录算法训练营第二天| 977. 有序数组的平方 、209.长度最小的有序数组、 59.螺旋矩阵II

解题思路:解法1:暴力解法,第一步将数组内元素遍历平方,第二步将数组内元素排序。时间复杂度:O(n + nlog n)解法2:双指针解法,左指针指向数组第一个元素,右指针指向数组最后一个元素,由于是升序排序,所以元素平方后较大的数会在数组的两头,通过左右指针指向的元素平方进行比较,平方后较大的元素从后往前存入创建的新数组中。时间复杂度:O(n)

2023-02-16 20:55:18 162

原创 代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素。

解题思路:二分查找,区间选择了左闭右闭的写法。遇到问题:由于写的区间是[left,right]的,所以while判断的应该是left):关于middle=left+(right-left)/2,可以写成是 left+((right-left)>>1)。位运算可以直接对二进制进行操作,不仅可以节约内存,还可以使程序运行速度更快。

2023-02-15 21:06:36 214 1

空空如也

空空如也

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

TA关注的人

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