自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 代码随想录学习Day 31

本题与之前的无重叠区间和射气球类似,其实就是合并区间后将得到的左边界和右边界作为一个新的区间,加入到result数组里就可以了。如果没有合并就把原区间加入到result数组。本题思路与前一道类似,代码只需稍作修改。当后一个区间左边界小于前一个区间右边界时说明这两个区间存在重叠部分,此时将count + 1,并更新右边界为二者中较小的值即可。此时前面出现过所有字母,最远也就到这个边界了。在遍历的过程中相当于是要找每一个字母的边界,

2024-04-26 20:36:35 435

原创 代码随想录学习Day 30

按照起始位置排序,那么就从前向后遍历气球数组,靠左尽可能让气球重复。从前向后遍历遇到重叠的气球,重叠气球中右边边界的最小值之前的区间一定需要一支箭。而气球3的左边界大于第一组重叠气球的最小右边界,所以再需要一支箭来射气球3。因为按照身高排序之后,优先按身高高的people的k来插入,后序插入节点也不会影响前面已经插入的节点,最终按照k的规则完成了队列。用一个字典来统计当前手中的钞票,每次找零时将消耗的钞票-1,如果当前钞票不满足找零条件则返回False,循环结束返回True。

2024-04-23 14:28:52 747

原创 代码随想录学习Day 29

思路:先对数组进行排序,保证数组中最小的值(也就是取反后损失最小的值)位于数组最前端。当从后往前遍历时,如果遇到左孩子大于右孩子的情况,还需要考虑之前遍历过程中candy[i]的值,不能直接赋值为candy[i + 1] + 1,而是要取candy[i + 1] + 1 和 candy[i] 最大的糖果数量,思路:先从前往后遍历,处理所有右孩子评分大于左孩子评分的情况;在从后往前遍历,处理左孩子评分大于右孩子评分的情况。全局最优:相邻孩子中,评分高的右孩子糖果比左边孩子多;评分高的左孩子糖果比右边孩子多。

2024-04-22 11:33:58 577

原创 代码随想录学习Day 28

题目链接讲解链接思路:最终利润是可以分解的。假如第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0]。相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。此时就是把利润分解为每天为单位的维度,而不是从 0 天到第 3 天整体去考虑。换个角度来看:就是把股票的价格波动写出来,单调上升就是盈利,题解就是每一段单调上升的总和。如[7, 1, 5, 10, 3, 6, 20,

2024-04-15 15:00:32 411

原创 代码随想录学习Day 27

首先想到的解法是先将s数组和g数组按照从小到大的顺序排序,然后用两个for循环来遍历两个数组,外层遍历g数组,内层遍历s数组,每次遇到满足g[i] < s[i]的情况时就将result+1,然后将s[i]置零代表这篇饼干已被使用过,并跳出当前层循环;这里必须外层遍历饼干,内层遍历胃口才可以,因为外层循环的i是固定移动的,内层的index只有在满足条件时才会移动,如果交换顺序就会导致一直在用最小的饼干来对比所有孩子的胃口,从而无法得出结果。思路:找局部最优,看能不能推出全局最优,并尝试举反例。

2024-04-12 23:26:53 623

原创 代码随想录学习Day 26

3.单层递归逻辑:通过row来遍历棋盘的行,col遍历棋盘的列。递归的下一层的棋盘一定比上一层的棋盘多一个数,等数填满了棋盘自然就终止(填满说明找到了结果),所以不需要终止条件。N皇后是因为每一行每一列只放一个皇后,只需要一层for循环遍历一行,递归来遍历列,然后一行一列确定皇后的唯一位置。因为解数独找到一个符合的条件(就在树的叶子节点上)立刻就返回,相当于找从根节点到叶子节点一条唯一路径,所以需要使用bool返回值。树的每一层递归对应棋盘的一行,深度对应n,宽度为n*n。

2024-04-09 15:38:53 719

原创 代码随想录学习Day 25

可以看出元素1在[1,2]中已经使用过了,但是在[2,1]中还要在使用一次1,所以处理排列问题不使用startIndex,而是需要一个used数组,标记已经选择的元素。3.单层搜索逻辑:重点在于如何在树层上去重,同一父节点下的同层上使用过的元素就不能再使用了,所以需要使用一个set来负责每层的去重。3.单层搜索逻辑:在排列问题中,每次都要从头开始搜索,例如元素1在[1,2]中已经使用过了,但是在[2,1]中还要再使用一次1。本题的是求自增子序列,所以不能对原数组进行排序,排完序的数组都是自增子序列了,

2024-04-08 16:09:29 1183 2

原创 代码随想录学习Day 24

组合问题和分割问题都是收集树的叶子节点,而子集问题是找树的所有节点。子集中集合是无序的,取过的元素不会重复取,所以写回溯算法的时候,for就要从startIndex开始,而不是从0开始。2.递归终止条件:当index位于字符串的末尾,并且path的长度为4时,意味着终止,此时将path中的4个字符串用“.”连接起来并存入result中就得到了一个结果。若合法则将其加入path中,然后从i+1的位置开始下一轮递归。本题属于切割问题,切割问题需要使用回溯算法来将所有的结果搜索出来,与前一题分割回文串是类似的。

2024-04-07 16:13:11 438

原创 代码随想录学习Day 23

因为对数组进行过排序,那么只需要判断i > startindex并且candidates[i] == candidates[i-1],就说明前一个同样的元素已经被使用过了,当前元素的处理可以直接跳过来实现去重。所以在递归调用自身时,startindex的选择不能是+1,而是要选择当前的i值,这样才能实现重复选取元素,并且不会出现重复的组合。2.递归终止条件:当切割到了字符串的末尾,也就是startindex的值与字符串的长度相等时,说明已经找到了一组分割的方案。难点:本题candidates 中的。

2024-04-02 11:48:01 1254

原创 代码随想录学习Day 22

1.回溯函数参数及返回值:需要定义两个全局变量result和path,result用来保存结果的集合,path用来保存符合条件的单个结果。1.回溯函数参数及返回值:定义字符串path来保存叶子节点的结果,result作为结果集,还有就是题目中的digits和用来表示遍历到第几个数字的index。3.单层搜索过程:for循环从startindex遍历到9,用path保存取到的元素i,backtracking递归调用自己向深处遍历,遇到叶子节点则返回。在递归函数的开始添加一个判断,如果sum>n,则直接返回。

2024-03-30 14:51:39 663

原创 代码随想录学习Day 21

1.递归函数参数及返回值:参数一定要有n,k,以及一个startIndex,这个参数用来记录本层递归的中,集合从哪里开始遍历(集合就是[1,...,n] )。2.递归终止条件:path这个数组的大小如果达到k,就说明找到了一个子集大小为k的组合,在树中path存的就是根节点到叶子节点的路径。回溯是递归的副产品,有递归就会有回溯,回溯操作一般出现在递归函数的下面。3.回溯函数遍历过程:回溯法一般是在集合中递归搜索,集合的大小构成了树的宽度,递归的深度构成的树的深度。已经选择的元素个数:len(path)

2024-03-29 16:29:54 900

原创 代码随想录学习Day 20

思路:采用递归方法,若root.val > high,判断左子树是否为空,若不空,递归遍历左子树,若空就返回null;二叉搜索树,所以要选取数组最中间的元素来作为根节点,然后两边的元素递归构造左右子树,这样才能保证左右子树的高度相差不超过1。1.递归函数参数及返回值:参数就是当前遍历的节点,不需要返回值,但需要定义一个全局变量pre来保存当前节点前一个节点的值。3.单层递归逻辑:进行反中序遍历,先遍历右子树,再遍历左子树,将每个节点的值改为其当前值与pre值的和。(反中序遍历),从最大的元素开始,

2024-03-28 17:59:38 492

原创 代码随想录学习Day 19

⑤要删除节点左右皆不空:最复杂的情况,需要将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。1.递归函数参数及返回值:参数就是根节点指针,以及要插入的元素,返回值为节点类型。2.递归终止条件:遍历到空节点,也就是找到了插入节点的位置,返回要插入的节点。1.递归函数参数及返回值:参数为当前根节点和要删除的值,通过返回值来删除节点。③要删除的节点左不空右空:让其父节点指向其左孩子,返回左孩子为根节点。①找不到要删除的节点:返回null。

2024-03-27 15:00:07 945

原创 代码随想录学习Day 18

思路:利用二叉搜索树的性质,其中序遍历序列是一个有序数组。所以先对二叉搜索树进行中序遍历,得到一个递增的数组后,再遍历整个数组,依次求相邻值的差,最后返回最小的差值即可。找到root == q,或者root == p,说明找到 q p ,则将其返回。1.递归函数参数及返回值:参数为根节点和要查找的p,q节点,返回值为TreeNode。求最小公共祖先,需要从底向上遍历,那么只能通过后序遍历(即回溯)实现从底向上的遍历。可以省去开辟数组的过程,需要用一个pre节点记录一下cur节点的前一个节点。

2024-03-26 14:49:39 998

原创 代码随想录学习Day 17

2.递归终止条件:当递归遍历的时候,如果传入的数组大小为1,说明遍历到了叶子节点了。应该定义一个新的节点,并把这个数组的数值赋给新的节点,然后返回这个节点。3.单层递归逻辑:先找到数组中最大值及其对应的下标,最大值作为根节点,下标用来划分左右子树;1.递归函数参数及返回值:参数是传入的数组,返回值是树的头节点。①若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;②若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;,因为先构造中间节点,然后递归构造左子树和右子树。

2024-03-25 15:56:39 578

原创 代码随想录学习Day 16

2.递归终止条件:采用递减的方式,让计数器count初始为目标和,然后每次减去遍历路径节点上的数值。递归函数是有返回值的,如果递归函数返回true,说明找到了合适的路径,应该立刻返回。原理:以后序数组的最后一个元素为切割点,先切中序数组,根据中序数组,反过来再切后序数组。简而言之就是通过后序数组和中序数组来确定左右子树,进而切割得到左右子树的后序和中序数组,然后进行递归就能求出整个树。所以使用层次遍历的方法比较简单,遍历每一层时都将该层的最左边节点的值保存下来,当遍历结束后将这个值返回即可。

2024-03-23 18:20:51 623

原创 代码随想录学习Day 15

3.单层递归的逻辑:分别求出传入节点为根节点的二叉树的左右子树的高度,然后如果差值小于等于1,则返回当前二叉树的高度,否则返回-1,表示不是二叉平衡树。3.单层递归的逻辑:因为采用的是前序遍历,所以要先处理中间节点,先把中间节点放进path中,2.递归终止条件:若当前节点为空节点,则终止并返回0,意为以当前节点为根节点的数高度为0.递归之后要进行回溯,因为要删除path中的节点,再加入新的节点得到新的路径。判断当前节点的左孩子是否存在,若存在,再判断当前节点的左孩子的左右孩子是否均为空,

2024-03-22 20:17:50 1245

原创 代码随想录学习Day 14

的思路来解决,因为要求的是二叉树的最大深度,那么在进行层次遍历的时候设置一个变量count用来记录当前遍历的层数,count初始为0,每遍历完一层将其值+1,最后返回该值即为二叉树的最大深度。在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。本题首先想到的就是采用层次遍历的做法,每遍历一层深度+1,当遇到第一个。

2024-03-22 17:37:28 586

原创 代码随想录学习Day 13

层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。需要借用一个辅助数据结构即队列来实现,要实现二叉树的反转,其实就是把每一个节点的左右孩子交换一下即可。,所以在递归遍历的过程中,也是要同时遍历两棵树。,前中后序以及层次遍历的选择。本题使用前序、后序和层次相对容易。根节点的左子树与右子树是不是相互翻转。对于二叉树是否对称,要比较的是。的,理解这一点就知道了。

2024-03-20 20:50:38 537

原创 代码随想录学习Day 12

写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。中序遍历(迭代法)是左中右,在遍历过程中先访问的是二叉树顶部的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是在把节点的数值放进result数组中),其。确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。

2024-03-19 20:21:56 619

原创 代码随想录学习Day 11

在进行push操作的时候,只要每次进入窗口的元素比前面的都大,就可以就可将前面的元素全部弹出,这样可以保证出口处的元素是最大值。所以大顶堆(堆头是最大元素),小顶堆(堆头是最小元素),可以直接用priority_queue(优先级队列)实现。如果定义一个大小为k的大顶堆,在每次移动更新大顶堆的时候,每次弹出都把最大的元素弹出去了,所以在本题中需要使用。,因为优先级队列对外接口只是从队头取元素,从队尾添加元素,再无其他取元素的方式,看起来就是一个队列。由于本题需要对频率排序,所以可以使用优先级队列。

2024-03-18 18:06:11 483

原创 代码随想录学习Day 10

在匹配左括号的时候,右括号先入栈,就只需要比较当前元素和栈顶相不相等就可以了,比左括号先入栈代码实现要简单。本题非常简单,只需要遍历字符串中的元素,将与栈顶元素不同的元素入栈,若相同则不入栈并弹出栈顶元素即可。不匹配的情况总共有三种:左括号多了、右括号多了以及左右括号不匹配。最后字符串遍历完之后,如果栈是空的,就说明左右括号全都匹配。第一种采用eval的方法,但速度较慢。

2024-03-17 13:45:55 847

原创 代码随想录学习Day 9

栈的内部结构,栈的底层实现可以是vector,deque,list 都是可以的, 主要就是数组和链表的底层实现。栈提供push 和 pop 等等接口,所有元素必须符合先进后出规则,所以栈不提供走访功能,也不提供迭代器(iterator)。,把que1最后面的元素以外的元素都备份到que2,然后弹出最后面的元素,再把其他元素从que2导回que1。所以用栈实现队列, 和用队列实现栈的思路还是不一样的,这取决于这两个数据结构的性质。使用栈来模式队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈。

2024-03-16 12:35:59 1001

原创 代码随想录学习Day 8

首先是暴力解法,遍历字符串,每当i能整除字符串长度时,就对字符串进行切片,保留开始到s[i-1]的部分作为子串,然后判断字串乘上n整除i的值能否组成主串。前缀表的任务是当前位置匹配失败,找到之前已经匹配上的位置,再重新匹配,此也意味着在某个字符失配时,前缀表会告诉你下一步匹配中,模式串应该跳到哪个位置。其次就是移动匹配的方法,符合条件的字符串一定是由前后相同的子串组成。最后就是KMP算法,KMP算法适合解决字符串出现在另一个字符串中的情况,在本题中,在由重复子串组成的字符串中,也就是相同前后缀的长度。

2024-03-12 11:24:43 993

原创 代码随想录学习Day 7

因为每次遍历至2k,然后反转了前k个字符之后,此时不需要判断后面的字符是什么情况,只需要直接再让i移动2k,进入下一次循环,此时上一步中剩余的字符就变成了本次循环遍历的2k个字符的一部分,而本次遍历的字符中前k个按照逻辑必须要进行反转,所以也就实现了将上一轮剩余的字符进行反转。首先能想到最简单的办法就是采用split()函数来分隔单词,然后将每个单词进行反转,之后再合并为列表,然后转换成用空格隔开的字符串,这样做需要额外开辟空间。设置一个for循环,令i每次移动的步长为2k,那么这两个条件合起来意思就是。

2024-03-10 14:57:13 479

原创 代码随想录学习Day 6

如果采用哈希法,去重会非常困难,虽然可以跟前面的四数相加采用类似的做法,两个for循环用来确定a和b的值,再用哈希法判断0-(a+b)是否存在,但这样做难以实现去重,且时间复杂度为O(n^2)容易超时。然后去遍历ransomNote,检查其中的字符是否在字典中,且字符的数量与出现的次数是否匹配。接下来进行判断,如果nums[i] + nums[left] + nums[right] > 0 则表示此时三数和偏大,因为数组是经过排序的,所以为了减小三数和,应该让right向左移动。最后返回count即可。

2024-03-08 19:48:46 505

原创 代码随想录学习Day 5

判断元素是否出现,元素作为key,所以数组中的元素作为key,有key对应的就是value,value存下标。map用来存放访问过的元素,因为遍历数组的时候,需要记录之前遍历过哪些元素和对应的下标,这样才能找到与当前元素相匹配的(也就是相加等于target)输出结果中的每个元素一定是唯一的,也就是说输出的结果的去重的,同时可以不考虑输出结果的顺序。由于题目规定输入的字符串均由小写字母组成,所以可以直接定义一个长度为26的全零数组作为哈希表,用来记录字符串中字符出现的次数。数组就是一张哈希表。

2024-03-07 21:45:29 967

原创 代码随想录学习Day 4

这里先求出两个链表的长度,并求出两个链表长度的差值,然后让curA移动到,和curB末尾对齐的位置,然后比较curA和curB是否相同,如果不相同,同时向后移动curA和curB,如果遇到curA == curB,则找到交点。使用快慢指针法,分别定义 fast 和 slow 指针,均从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。要寻找链表中的倒数第n个节点,比较简单的方法就是利用快慢指针之间的距离,

2024-03-06 20:02:05 977

原创 代码随想录学习Day 3

要注意题目中获取第n个节点其中的n都是从0开始的.

2024-03-05 14:51:53 890

原创 代码随想录学习Day 2

所以可以考虑使用双指针法,使用两个指针指向数组的两端。②窗口的终止位置就是for循环的索引,起始位置则是如果当前窗口中的sum>target,那么窗口就需要向前移动,将窗口变小,移除窗口中的第一个值。滑动窗口的意思就是不断调节子序列的初始位置和末尾位置,从而得到题目需要的结果。暴力解法为设置两个for循环,然后不断的寻找符合条件的子序列,时间复杂度为O(n^2),在力扣上会超时。滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。滑动窗口也是双指针法的一种。

2024-03-03 14:25:17 444

原创 代码随想录学习Day 1

写二分法,区间的定义一般为两种,左闭右闭即[left, right],或者左闭右开即[left, right)。①左闭右闭法:定义target在。

2024-03-01 18:43:48 691 1

空空如也

空空如也

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

TA关注的人

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