自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

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

continue;continue;都是可以的,这也是很多同学做这道题目困惑的地方,知道也行而也行,但是就想不明白为啥。所以我通过举[1,1,1]的例子,把这两个去重的逻辑分别抽象成树形结构,大家可以一目了然:为什么两种写法都可以以及哪一种效率更高!这里可能大家又有疑惑,既然也行而也行,那为什么还要写这个条件呢?直接这样写 不就完事了?continue;其实并不行,一定要加上或者。

2023-09-06 08:27:13 93

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

93.复原IP地址。

2023-09-01 10:19:05 80

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

为什么 used[i - 1] == false 就是同一树层呢,因为同一树层,used[i - 1] == false 才能表示,当前取的 candidates[i] 是从 candidates[i - 1] 回溯而来的。剪枝操作:对总集合排序之后,如果下一层的sum(就是本层的 sum + candidates[i])已经大于target,就可以结束本轮for循环的遍历。在处理组合问题的时候,递归参数需要传入startIndex,表示下一轮递归遍历的起始位置,这个startIndex就是切割线。

2023-08-29 09:10:46 87

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

这题就是多了求和的条件,所以判断的时候多加上对于求和的判断,以及剪枝时候对于如果统计的sum>target_sum了那就也return剪枝。那么终止条件就是如果index 等于 输入的数字个数(digits.size)了(本来index就是用来遍历digits的)。再来看参数,参数指定是有题目中给的string digits,然后还要有一个参数就是int型的index。例如输入用例"23",两个数字,那么根节点往下递归两层就可以了,叶子节点就是要收集的结果集。216.组合总和III。

2023-08-26 09:46:10 81

原创 代码随想录算法训练营第21天| 理论基础 77. 组合

这意味着,如果`self.path`在后续的操作中发生了变化(例如,在回溯过程中通过`pop()`方法删除了一个元素),那么在`self.result`中已经保存的`self.path`的内容也会随之发生变化。为了更好地理解,你可以尝试删除`copy()`,然后运行代码。你会发现`self.result`中的所有列表都是空的(或者它们的内容不是你期望的结果),因为在回溯算法的执行过程中,`self.path`被多次清空,而`self.result`只保存了`self.path`的引用,没有保存它的内容。

2023-08-25 10:24:41 40

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

当你在`traversal`函数内部修改`node.val`时,你实际上是在修改外部`root`所引用的那个对象的值,因为`node`和`root`在这里引用的是同一个对象。因此,即使`traversal`函数结束后`node`变量消失了,对`node.val`的修改仍然会保留在`root`所引用的对象中,所以你看到的是树中节点的值已经被更改了。‘‘’‘’‘’当我们采用左闭右开区间(即`[left, right)`)来表示一个范围时,这意味着该范围包括`left`但不包括`right`。

2023-08-24 20:11:52 68 1

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

剩下的情况,就是cur节点在区间(p->val <= cur->val && cur->val <= q->val)或者 (q->val <= cur->val && cur->val <= p->val)中,那么cur就是最近公共祖先了,直接返回cur。如果 cur->val 小于 p->val,同时 cur->val 小于 q->val,那么就应该向右遍历(目标区间在右子树)。终止条件就是找到遍历的节点为null的时候,就是要插入节点的位置了,并把插入的节点返回。450.删除二叉搜索树中的节点。

2023-08-23 13:48:13 30

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

在结束左子树的所有递归调用后,`self.pre` 的值会是左子树中最右边(也就是值最大的)的节点。在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。图中节点10的左子树返回null,右子树返回目标值7,那么此时节点10的处理逻辑就是把右子树的返回值(最近公共祖先7)返回上去!这也是回溯的核心概念,即在递归返回时,我们可以继续使用在递归深入时保存的状态或信息,此处就是 `self.pre` 的值。

2023-08-22 13:33:33 40 1

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

左右的话就是递归调用函数,接下来t1 的左子树是:合并 t1左子树 t2左子树之后的左子树。t1 的右子树:是 合并 t1右子树 t2右子树之后的右子树。中序遍历,左遍历,中间判断如果当前节点val大于max-val就更新否则就不符合二叉搜索树false,右遍历,当左右都true则true。如果root为空,或者找到这个数值了,就返回root节点,因为在空的情况说明要么就是没找到要么就是root本身为空。如果当前节点<val,就说明val大了,找右子树,反之亦然。是的,二叉搜索树也可以为空!

2023-08-19 11:14:46 31

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

113是递归函数不返回值,有点类似于之前层序遍历那种,总的result,然后一个vec去保存每一条路径,如果找到了叶子结点且cot=0,就存下来,这要注意存的是vec的copy,因为vec由于回溯会pop,所以我们得拷贝以后先存下来路径,遍历过程和112一样,就是要记得对cot和vec都回溯。记得主函数的时候要先判断root是否为空,空就是false,然后放入递归func,这里的count要减掉root.val因为是从root往下遍历了。第五步:切割后序数组,切成后序左数组和后序右数组。

2023-08-18 15:13:35 102 1

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

1. `self.get_height(root.left)` 会调用当前对象(`self`)上的 `get_height` 方法,并以当前 `root` 节点的左子节点作为其参数。这是一个新的赋值表达式。4. 如果 `left_height` 是 `-1`,则执行 `if` 块内的代码(在这种情况下,是 `return -1`)。当遇到左叶子节点的时候,记录数值,然后通过递归求取左子树左叶子之和,和 右子树左叶子之和,相加便是整个树的左叶子之和。所以如果当前遍历的节点是叶子节点,那其左叶子也必定是0,

2023-08-17 10:26:37 49 1

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

完全二叉树就是求左子树和右子树的深度,如果深度一样则说明满足满二叉树,节点数量为2^深度-1,就是要注意深度是从1开始的,如果0开始的话就要2^(d+1)-1 或者2<<d-1。后序遍历,先求它的左子树的深度,再求右子树的深度,最后取左右深度最大的数值 再+1 (加1是因为算上当前中间节点)就是目前节点为根节点的树的深度。递归,后序遍历,如果left为空,right不空则结果为right+1;right空,left不空则right+1;高度就是看叶子有多高,从下往上,深度的话就是反过来从上往下。

2023-08-16 10:49:53 92 1

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

就是遍历每层,然后存下来这层的所有子节点给下次遍历用,这次遍历次数就是这层的size。自下往上的话就是把自上往下的结果反转就可以:res[::-1]101. 对称二叉树 (优先掌握递归)226.翻转二叉树 (优先掌握递归)--后面部分继续明天补。

2023-08-14 16:31:28 65

原创 代码随想录算法训练营第12天| 二叉树理论基础● 递归遍历 ● 迭代遍历● 统一迭代

理论基础解题过程中二叉树有两种主要的形式:满二叉树和完全二叉树满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层(h从1开始),则该层包含 1~ 2^(h-1) 个节点。

2023-08-11 13:43:55 47 1

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

然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。

2023-08-10 19:27:49 24 1

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

这种表达式的话是更利于计算机计算的,利用栈的话就可以在遇到数字的时候不断加入,如果是运算符,就取出两个数字,由于栈是先进后出,所以第二个取出来的数字应该是在运算符的前面,这边在-和/号的时候要注意,最后遍历完的话把栈里最后一个元素弹出符合代码规范(其实不弹出也没事)情况三:遍历字符串匹配的过程中,如果栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号 return false。情况二:遍历字符串匹配的过程中,发现栈里没有我们要匹配的字符。三种情况,左括号多,括号不匹配,右括号多。

2023-08-09 09:00:44 38 1

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

top的时候要返回栈顶元素,也就是末尾元素,其实就是直接[-1],也可以调用pop函数然后把元素再放回去。HP STL 其他版本的C++ STL,一般是以HP STL为蓝本实现出来的,HP STL是C++ STL的第一个实现版本,而且开放源代码。栈的内部结构,栈的底层实现可以是vector,deque,list 都是可以的, 主要就是数组和链表的底层实现。C++标准库是有多个版本的,要知道我们使用的STL是哪个版本,才能知道对应的栈和队列的实现原理。的同类操作的时间复杂度是O(n)。

2023-08-08 10:11:09 65

原创 代码随想录算法训练营第八天| ●28. 实现 strStr()●459.重复的子字符串●字符串总结 ●双指针回顾

KMP确实挺难的,卡哥视频我看了两遍才稍微明白了点,就是在一个字符串里面查找是否出现过另一个字符串,就是去找最长相等的前缀后缀,得到next数组,数值为相等时➕1,不相等的时候那么此时我们要看它的前一个字符的前缀表的数值是多少。为什么要前一个字符的前缀表的数值呢,因为要找前面字符串的最长相同的前缀和后缀。也是用KMP算法,重复的子字符串就是字符串去除最长相等的前缀后缀以外的部分。前缀:指不包含最后一个字符的所有以第一个字符开头的连续子串。后缀:指不包含第一个字符的所有以最后一个字符结尾的连续子串。

2023-08-06 22:36:28 35

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

这道题的关键在于每次循环处理反转的时候要2k处理吧,前k个反转后k个不反转,所以下一次就得跳过这个2k,最后剩下的值如果不满足2k也全部反转,我感觉其实是可以不用单独拆出来写的,合并进去写的话因为小于k所以一定符合前面的条件进行了反转。这道题涉及到的操作还蛮多的,首先先去除空格元素,双指针移除元素,除了首单词的情况,其他单词前面均需要加上空格,然后双指针同时移动赋值单词直到遇到空格或者字符串结尾。然后重新设置一下list长度!很重要,slow指针的大小即为去除多余空格后的大小,不然就会包括多余空格。

2023-08-05 21:30:19 31 1

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

题目要求组合不能重复,所以要对三元素都去重,对于最左边的i来说,和前面一个遍历过的i-1匹配,如果相等则说明已经找过对应的组合了则跳过,不能和后面i+1去比较,这样的话只是在对组合里元素去重复而已没有用。然后判断sum是否为0,<0说明太小,left变大一点, >0太大,right变小一点。先使用dict存储nums1和nums2中的元素及其和a+b,然后再遍历剩下两个数组,如果 0-c-d 存在于nums3和nums4, 也就是a+b+c+d=0,那就存入a+b出现的次数,因为会有重复的情况。

2023-08-04 11:32:52 52 1

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

哈希表是根据关键码的值而直接进行访问的数据结构。

2023-08-03 18:03:12 92

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

首先让快指针先走n+1步,因为删除的时候需要慢指针指向删除节点的前一个,这样就可以直接跳过删除节点指向下一个节点。防止节点修改,要先保存下来pre(1)和next.next(2)的值,交换的路线的话画图更清晰些,最后记得往下遍历,每组都是两辆交换,所以连跳两个next, cur = cur.next.next。求出两个链表的长度,并求出两个链表长度的差值,然后让curA移动到,和curB 末尾对齐的位置,让curA和curB在同一起点上(末尾位置对齐)一起走,如果相遇了那就是相交的起点。

2023-08-02 14:53:50 31

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

每次对链表具体位置操作的时候,第n个节点一定要是cur.next,因为只有这样我们才可以对第n个节点的前一个节点也就是cur进行操作,无论是add delete,都需要知道前一个节点的信息。使用虚拟头节点,这样就不用区分是否是头节点,只要将其开始指向head,然后不断遍历找出==val的节点然后cur.next=cur.next.next,结束遍历以后返回。就好,不返回之前的head是因为head可能已经被删了,虚拟头节点的next才是新链表的头节点。一定要注意题目说的下标从0开始。203.移除链表元素。

2023-07-29 15:11:25 33

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

排序的整数数组,但是包含了负数,所以比较大的值一般来说会出现在两边,所以从两边开始比较最好,然后倒序放到result数组里,这里我因为用的是python所以list给了初始值和长度这样方便赋值。双指针,滑动窗口:外层循环是终止位置指针,不断对子数组求和,如果超过target,则开始记录目前子数组的长度,同时也可以对起始指针进行移动,去找下一个求和>=target的子数组。但是,这里的重点是,它们并不是新的列表,而是对原始列表的引用。因此,你最后得到的是一个二维列表,但所有的子列表实际上都是同一个列表。

2023-07-28 14:04:33 25

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

代码随想录算法训练营第一天

2023-07-27 09:52:08 170

空空如也

空空如也

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

TA关注的人

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