自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 代码随想录算法训练营第三十八天|509. 斐波那契数 ● 70. 爬楼梯 ● 746. 使用最小花费爬楼梯

然后因为递归中有很多重复计算,就写一个表来存储已经被计算过的数值,这样递归的第一条o(n)深度的从底顶就已经把基本后续需要的值给存到表里了。在写题之前,先看了左神的关于一维动态规划的一些视频。底部的数据依赖其前部,所以有从顶到底的动态规划,也就是随想录的分析做法。前几道题属于是摸索,都是照葫芦画瓢,从第三题开始写一些自己的心得。空间上还可以再优化,让dp数组只有两个长度。746. 使用最小花费爬楼梯。这是从底到顶的记忆化动态规划。先是使用递归暴力的写出来。这个会超时(无记忆)

2024-04-15 23:39:36 215

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

这样最后一个区间会被遗漏(如果与上一个不重叠就存上一个,如果重叠就改写自己),所以别忘了遍历结束后将最后一个区间也加入结果集中(虽然漏下了存入的操作,但是已经被判断结束了)如果与上一个重叠:就把该区间变为该区间与前一个区间的合区间(因为每次读取比较的区间都是前一个区间,这样下一个区间就能与合并后的大区间比较)先将第一个区间压入result,然后从i=1开始遍历,如果与结果集末尾(也就是上一个)区间重叠,改变末尾结果集,否则不重叠就把该区间压入。如果与前一个不重叠:就把上一个区间存入结果中。

2024-04-14 17:32:10 224

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

但是这种判断条件会使插在单调坡中的平坡被误判成功,所以只有在判断成功时才有把后差和赋值给前差和的操作,因为单调操作时前差和一直都满足同一个条件,不需要再赋值。对于局部的处理在于对单调序列的处理,如果一个元素的前元素差和后元素差满足分别大于和小于0就满足摆动条件。对第一个节点的处理可以不用特殊化,视为其前面有一个相同节点,即初始化前元素差为0时第一个节点自动符合条件。对平坡的处理:对平坡最后一个节点进行判断,之前的平坡节点都默认删掉。所以判断符合的条件为。自己想的不知道处理局部的思路在哪。

2024-04-10 18:07:15 228

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

子集里面的元素是无序的,{2,1}和{1,2}是一样的,所以for循环从startindex开始。若是有序就从0开始。而且这道题收集的是树上的叶子节点,每个都要收集,别忘了空集。是去重和子集的一道复合题。注意去重的简便方法有用startindex和used数组两种,当递归时为i+1都可以用,递归时传递i则只能用used数组(为了跳过已入栈的元素)与昨天的分隔子串很像。要点在于如何分割ip串,终止条件(有三个点后判断最后一段是不是地址),如何判断是不是地址,在s串本身上操作很方便。

2024-04-02 12:14:41 233

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

常规组合的回溯做法,区别在于可以重复使用同一元素,所以递归时参数继续用当前的index值就行。同时返回条件不用对数目进行判断,只判断sum和就行。但是不能在我的代码的基础上直接添加,因为我的sum是全局变量,会浮动,而for循环中的sum使用时会用当前的值,所以用这个剪枝时应把sum当成参数。有一个剪枝操作,当sum大于target时,其for循环后续的值也会大于target,但还会继续把for遍历完,在for循环中改为。具体看讲解就行,讲的很仔细,尤其是去重。可以避免后续多余的遍历。去重去不明白,寄了。

2024-04-01 22:15:53 318

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

不停找数组中间值作为节点,然后向左右递归,没什么可说的。写了两种写法发现返回值为空比返回值为节点速度要快。经典双指针用法,没什么好说的,遍历顺序为右中左。递归做法注意返回值,参数,结束条件,循环条件。108.将有序数组转换为二叉搜索树。538.把二叉搜索树转换为累加树。669. 修剪二叉搜索树。

2024-03-31 23:38:32 136

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

i那里的剪枝可以这么理解,假设从i开始取,则从i到n一共有n-i+1个元素,而当前还需要k-path.size()个元素,所以必须满足n-i+1>=k-path.size(),移项就可以得到i<=n+1-(k-path.size())有一说一,再写参数时候写的很蒙,感觉回溯做法只写一个大致参数就可以开始实战了,其他的参数在写的时候需要时自然会补上。由于是回溯做法,还要传入一个参数来递归,所以传入一个head,head表示的是处于num数组的位置。常用操作,使遍历个数不足要求时提前结束。写了一个小时,好累。

2024-03-31 00:27:47 328

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

由于二叉搜索树的性质,如果一个节点的值介于两个要找的值之间,那这两个值必然在该节点的左右两子树,此节点的左右子树便与另外一个值不相连,由此该节点就是公共祖先。其右子树的最左节点是应被删除节点的后继,删除节点后应调整其后继到其位置上。所以将其右子树的后继的值赋给应被删除的值,这时其后继的值就有两个了,在被替换值的应被删除的节点的右子树递归的删除该后继值,直到删到叶节点。递归的在函数中找查,如果值大于当前节点的值,就在右子树中查找,小于则在左子树中查找。如果没有右子树,就将其左子树的值直接返回。

2024-03-28 20:36:19 266

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

由于中序遍历相当于把一颗二叉树所有节点全水平放在一条直线上,这样判断p和q节点在节点的哪边就很方便找了,同时为了方便找查,使用了哈希表中的unordered_map容器,遍历二叉树并存储,key来存储val值,value来存储下标。本来想着用map来,但是用unordered_map是一样的(而且查询效率更高,为1,map查询效率为logn),因为中序遍历下来节点的相对左右次序是不变的,先被遍历的直接赋值1,然后依次2,3,4。从头节点开始,如果头节点的值等于q或p的值,就直接返回。

2024-03-27 16:55:21 760

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

再确立返回条件,每次碰到叶节点时返回,然后根据其深度来判断是否更新结果(只有深度更大才更新,深度相等是不行的,以免更新的结果不是最左下角)。递归做法,返回值是树节点指针,参数为遍历和遍历的区间首尾的int值。层序遍历的做法要更巧妙,没有像我一样用容器申请多余的空间,而是利用循环中的计数i,在i计数为第一个时存储到变量result中,这样遍历结束后result中存储的是最后一层的第一个数,即树左下角的值。自己的做法很简单,层次遍历,将每一层的第一个元素放进一个容器里,最后检查返回容器的最后一个元素。

2024-03-25 21:04:32 304

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

如果节点为空就返回空(什么也不干,结束这条线),不为空就加上该节点的值,再判断该节点是否是叶节点,是叶节点就压入v中并返回,不然就加上->,向左右子树递归。这时又出现了一个错误,那就是当这棵树只有根节点一个节点的情况,由于我们先将根节点的值初始化了,然后传进左右节点递归(因为想要去不停的加->num),这种情况下就没有叶节点了,无法返回。递归查看每个节点的左右子树高度,如果左右子树不为平衡二叉树就返回-1(左不为平衡树,右不为平衡树,左右相减不满足平衡树规律),最后判断根节点高度是否为-1来返回是否。

2024-03-22 23:42:45 276

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

遍历节点时,用队列来存储,每当队列头节点出队列,都检查是否有左右节点并入队列。在每轮循环开始前都统计队列里有多少元素,里面的元素都是该层次要遍历的节点,通过统计元素数目防止将节点出队列带来的新节点遍历到,本层元素全出队列后剩下的就是下一层的遍历元素。最初想法是像层次遍历一样,层次遍历中出队列的元素存到一个新队列里,加入队列的元素同时加入到一个栈里。然后由于加入栈中的时候顺序已经相反,所以新队列循环出队列并为其左右子树赋值。翻转整个树,只要遍历节点,然后翻转他的子节点就行了,可以用先序,后序,层次遍历。

2024-03-20 22:05:48 316

原创 代码随想录算法训练营第十四天|递归遍历 ● 迭代遍历● 统一迭代

我的做法是邓俊辉版清华大学数据结构的一种做法,循环体内容为:从头节点一直向左遍历,每次遍历就输出val并把右子树存储。头节点一直向左遍历时实际上就已经把父节点和左节点都遍历到了,所以遍历完之后去找右节点。先将头节点入栈,然后出栈,先后将右节点和左节点入栈。当一个节点出栈时,如果有左右节点,按先右后左的次序入栈。与随想录先序做法基本一致,先序遍历得到结果是中左右,后序得到是左右中,可以改动先序遍历得到中右左,然后在反转容器,即可得到答案。改动只需将节点出栈时将右子树先入左子树后入,改为左子树先入右子树后入。

2024-03-19 21:54:31 196

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

对于频率统计想到了map,但是想不出简单的排序方法,于是看了一下讲解是用堆,一直都没接触过堆,感觉颇有收获,很好用,明白堆之后感觉简单了很多。双端队列模拟滑动窗口标准做法,没啥好说的。注意队列里存的是下标,不然不能判断何时将队列元素从头出队列。347.前 K 个高频元素。239. 滑动窗口最大值。

2024-03-18 22:55:40 180

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

也是一道常规题,遍历字符与栈顶相同(注意判断栈是否为空,为空直接入栈)就出栈,否则入栈。常规做法,碰见左括号入栈,碰到右括号时如果栈非空并且栈顶是对应左括号,则出栈并继续循环,否则返回false。字符串遍历结束后,如果栈空,返回真,否则返回假。在碰到左括号时,入栈相应的右括号。碰到右括号时,对栈顶的括号进行比较。思路基本一致,在遍历字符串前加了对字符串奇偶的判断,如果字符串为奇数,则必不可能匹配。与随想录做法基本一致,随想录对字符串从头到尾遍历,然后从栈输出后反转。150. 逆波兰表达式求值。

2024-03-16 16:07:35 178

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

由于队列出了之后再进队列顺序不变(不像栈一样),没必要用两个队列,由于队列自带size函数,出队列时直接确定size为总长-1,然后全部头出尾入,最顶端的元素就是之前尾端的元素(也就是栈顶的元素),出队列即可,pop的复杂度为O(n)。用栈来模拟队列只要用两个栈,一个负责存储,而需要输出时就把存储栈元素按规则存到另一个栈里,这样在第二个栈里面的输出顺序就和栈一样了。pop方法:当输出栈不为空时,直接从里面输出。为空时,将输入栈里面所有元素全出栈并入栈到输出栈里(这时序列颠倒),然后从输出栈中出栈。

2024-03-15 14:19:42 279

原创 代码随想录算法训练营第九天|KMP

(举个例子,ababj,当第二个b的下一个也就是j的时候不一样了,传回第一个b)。所谓next数组,也就是前缀表,数组中每一项存的是其最长相等前缀的位置,如abab,第二个b对应的next数组存的是第一个b的位置。用处是当子数组的下一个数与父数组对不上时,直接把子数组的位置传回其next数组所存位置,这样由于next数组的前缀和传之前的前缀相等,就不需要再比较了。当子串的下一个和父串当前的数不同时,利用next数组退回,直到找到一样的或子串完全退回去(再次从子串的第一个开始比)但是这次也是复现出来了。

2024-03-14 23:11:37 244

原创 代码随想录算法训练营第八天|344.反转字符串● 541. 反转字符串II● 卡码网:54.替换数字● 151.翻转字符串里的单词● 卡码网:55.右旋转字符串

从头节点开始遍历,如果是空格就++,直到找到第一个不为空格的字符,即为单词的首字母,然后寻找该字母后的第一个空格,空格前一位即是该单词的最后一个字母,循环往复直到遍历完整个字符串。在去除空格时,使用了双指针的算法,当快指针不指向空格时,如果慢指针此时不为0,就填一个空格(该空格为单词间的空格,不为0是避免出现前导空格),然后填充单词直至快指针指向空格。每当i指针走到空格时,就翻转前面的字符串(即一个单词),然后更新单词头部指针,当指针走到字符串尾部时,也进行一次翻转(或条件)如果超出就直接反转剩余字符。

2024-03-13 21:59:42 917

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

然后开始寻找查找满足条件的结果,循环条件为while(left<right),当i,left,right指针所在数字的和大于0时,使right--,小于0时,使left++。先将前两个数组用二重循环存入map中(因为map可以存储key和value,让key为a+b的值,value为a+b出现的次数),然后再用二重循环,去寻找map中是否有key为(0-c-d)的数,如果有就证明,此时有对应的value组四数之和为0的数,更新计数。此处有细节,因为排序过了,所以当第一个数字大于0时,直接返回。

2024-03-13 00:33:26 306

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

如果用语言手造哈希表的话,应尽量避免不同的key值用函数计算的结果是一个(发生这种情况要额外解决,哈希表不同值存储的位置应不同),所采用的方法是余数法,先确定给定的数据大小,再确定表长(数据数量/表长=0.7~0.8),然后取p为不大于表长的最大质数,哈希函数为key%p。我自己的想法就是常规思路,如果n不为1就一直循环,先将n入哈希表,再将每个n变成其各个位上的数字平方和相加,在哈希表中寻找n,如果寻找的到n,证明该数n不停的在循环,这时候返回false,否则当n是1时退出,返回true。

2024-03-11 23:57:42 473

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

有交点的话,我让两个链表的尾节点分别与他们的头节点相连,然后两个分别指向两个链表的指针按不同的移动距离循环,最终会找到地址相同的点,即交点,再把链表复原即可。如果两个链表的做法有交点,那两个链表自交点起的末尾一定是一样的那就可以把两个链表尾对其,然后然后从短的那个链表的头节点开始依次比对是否有地址相等的点,找得到就是有交点,反之则没有。第一,也是最根本的错误:当两个链表的尾节点地址相同的时候,他们也就是一个尾节点,让两个链表的尾节点分别与他们的头节点相连是不现实的,因为这会让同一个尾节点赋值两次。

2024-03-10 21:53:32 933

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

我的写法是只有在末尾添加新节点时,才给原链表的末节点赋一个确定的next(因为末尾节点的next是什么没意义,用指针法要用末尾节点的next==NULL来中止,但是数组法可以用length来控制)。做一个虚拟的头节点指针,使其和head指针不断前前,每将head指针的next改变就将两个指针向前移动,直到head指针为0,双指针做法,只将链表遍历了一次,比我的做法要更快更好。在看见反转之后第一个想法是用栈,先顺序遍历一遍,把每个指针都存到栈里,再依次出栈,让先出栈的指针的next指向下一个出栈的指针。

2024-03-08 21:44:52 872

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

令j指针向前走,算范围内的sum和,当sum和大于等于target的时候,因为是取长度最小的子数组,所以j不需要再往前走了,而是记录当前长度,再去处理i,当处理到范围内sum和小于target时,这时已经获取j在此处以及之前的最小长度,j++。将while(sum>=target)写成了if(sum>=target),这样再范围内新加了一个特大数的时候,由于不能循环处理范围,将得不到最小的距离,而且当j走到num.size()时,数组将停止循环,会剩余i没有被处理。组成的新数组,要求也按。

2024-03-07 21:24:12 1305

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

704.二分查找文档讲解:代码随想录;视频讲解:手把手带你撕出正确的二分法 | 二分查找法 | 二分搜索法 | LeetCode:704. 二分查找_哔哩哔哩_bilibili状态:做出来了//算法和程序设计技术的先驱高德纳曾说过:虽然二分查找的基本思想相对简单,但细节可能会非常棘手。第一次接触二分查找的代码是b站上的一个教程视频:二分查找为什么总是写错?_哔哩哔哩_bilibili这个视频将二分查找的初始边界定为了-1和N(并非N-1),做法是根据题目确定一个边界条件,将给定的数组

2024-03-06 12:27:20 1349

空空如也

空空如也

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

TA关注的人

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