![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
代码随想录算法训练营
文章平均质量分 77
aurora_devops
流水不腐 户枢不蠹
展开
-
day17 110.平衡二叉树 257. 二叉树的所有路径 404.左叶子之和
首先要明确左叶子的定义:节点A的左孩子不为空,且左孩子的左右孩子都为空(说明是叶子节点),那么A节点的左孩子为左叶子节点。这个函数通过栈模拟的后序遍历找每一个节点的高度(其实是通过求传入节点为根节点的最大深度来求的高度)。这道题目要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。判断一个树的左叶子节点之和,那么一定要传入树的根节点,递归函数的返回值为数值之和,所以为int。判断当前节点是不是左叶子是无法判断的,必须要通过节点的父节点来判断其左孩子是不是左叶子。原创 2023-03-07 15:44:47 · 178 阅读 · 0 评论 -
day16 104.二叉树的最大深度 559.n叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数
二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数后者节点数(取决于高度从0开始还是从1开始)二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数后者节点数(取决于高度从0开始还是从1开始)二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)而根节点的高度就是二叉树的最大深度,所以本题中我们通过后序求的根节点高度来求的二叉树最大深度。原创 2023-03-07 09:53:55 · 193 阅读 · 0 评论 -
day15 层序遍历 226.翻转二叉树 101.对称二叉树
判断对称二叉树比较的是两个子树的里侧和外侧的元素是否相等,我们要通过递归函数的返回值来判断两个子树的内侧节点和外侧节点是否相等,因此本题遍历只能是“后序遍历”。思想:需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。广度优先遍历也就是层序遍历,层数遍历也是可以翻转这棵树的,因为层序遍历也可以把每个节点的左右孩子都翻转一遍。前序遍历是中左右,每次先处理的是中间节点,那么先将根节点放入栈中,然后将右孩子加入栈,再加入左孩子。原创 2023-03-03 23:32:43 · 158 阅读 · 0 评论 -
day14 二叉树理论基础 递归遍历 迭代遍历 统一迭代
平衡二叉搜索树:又被称为AVL(Adelson-Velsky and Landis)树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。C++中map、set、multimap,multiset的底层实现都是平衡二叉搜索树,所以map、set的增删操作时间时间复杂度是logn。## 二叉树的存储方式二叉树可以链式存储,也可以顺序存储。链式存储方式就用指针, 顺序存储的方式就是用数组。顺序存储的元素在内存是连续分布的,而链式存储则是通深度优先遍历原创 2023-02-28 19:50:56 · 237 阅读 · 0 评论 -
day13 239. 滑动窗口最大值 347.前 K 个高频元素 总结
第一感可能会想用一个大顶堆(优先级队列)来存放这个窗口里的k个数字,这样就可以知道最大的最大值是多少了, 但是问题是这个窗口是移动的,而大顶堆每次只能弹出最大值,我们无法移除其他数值,这样就造成大顶堆维护的不是滑动窗口里面的数值了。所以不能用大顶堆。此时我们需要一个队列,这个队列呢,放进去窗口里的元素,然后随着窗口的移动,队列也一进一出,每次移动之后,队列告诉我们里面的最大值是什么。每次窗口移动的时候,调用que.pop(滑动窗口中移除元素的数值),que.push(滑动窗口添加元素的数值),然后que.f原创 2023-02-27 23:09:40 · 198 阅读 · 0 评论 -
day11 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值
方法一:从栈中弹出剩余元素,此时是字符串ac,因为从栈里弹出的元素是倒序的,所以再对字符串进行反转一下,就得到了最终的结果。逆波兰表达式即后缀表达式,后缀表达式对计算机来说是非常友好的。方法二:拿字符串直接作为栈,省去了栈还要转为字符串的操作。逆波兰表达式即后缀表达式,后缀表达式对计算机来说是非常友好的。方法二:拿字符串直接作为栈,省去了栈还要转为字符串的操作。有效的括号有三种不匹配的情况:1. 第一种情况,字符串里左方向的括号多余了 ,所以不匹配。原创 2023-02-26 12:17:58 · 190 阅读 · 0 评论 -
day10 栈与队列理论基础 232.用栈实现队列 225. 用队列实现栈
优化:使用一个队列就够了,一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时再去弹出元素就是栈的顺序了。栈是以底层容器完成其所有的工作,对外提供统一的接口,底层容器是可插拔的(也就是说我们可以控制使用哪种容器来实现栈的功能)。所以STL中栈往往不被归类为容器,而被归类为container adapter(容器适配器)。用两个队列que1和que2实现队列的功能,que2其实完全就是一个备份的作用。栈和队列是STL(C++标准库)里面的两个数据结构。原创 2023-02-24 21:52:41 · 126 阅读 · 0 评论 -
day9 28. 实现 strStr() 459.重复的子字符串 字符串总结 双指针回顾
字符串是若干字符组成的有限序列,也可以理解为是一个字符数组,但是很多语言对字符串做了特殊的规定,接下来我来说一说C/C++中的字符串。在C语言中,把一个字符串存入一个数组时,也把结束符 '\0’存入数组,并以此作为该字符串是否结束的标志。在C++中,提供一个string类,string类会提供 size接口,可以用来判断string类字符串是否结束,就不用’\0’来判断是否结束。vector< char > 和 string 有什么区别?原创 2023-02-24 11:14:47 · 180 阅读 · 0 评论 -
day8 344.反转字符串541. 反转字符串II 剑指Offer 05.替换空格 151.翻转字符串里的单词 剑指Offer58-II.左旋转字符串
首先扩充数组到每个空格替换成"%20"之后的大小。i指向新长度的末尾,j指向旧长度的末尾。思路:1. 反转区间为前n的子串2. 反转区间为n到末尾的子串3. 反转整个字符串seStr(string s, int k) { for (int i = 0; i < s.size(); i += (2 * k)) { // 1. 每隔 2k 个字符的前 k 个字符进行反转 // 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符原创 2023-02-22 20:52:26 · 313 阅读 · 0 评论 -
day7 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和
day7 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和。首先定义 一个unordered_map,key放a和b两数之和,value 放a和b两数之和出现的次数。2. 遍历大A和大B数组,统计两个数组元素之和,和出现的次数,放到map中。3. 定义int变量count,用来统计 a+b+c+d = 0 出现的次数。4. 在遍历大C和大D数组,找到如果 0-(c+d) 在map中出现过的话,就用count把map中key对应的value也就是出现次数统计出来。5. 最后返原创 2023-02-22 16:05:53 · 366 阅读 · 0 评论 -
day6 哈希表理论基础242.有效的字母异位词349. 两个数组的交集202. 快乐数1. 两数之和
std::set和std::multiset底层实现都是红黑树,std::unordered_set的底层实现是哈希表, 使用unordered_set 读写效率是最高的,并不需要对数据进行排序,而且还不要让数据重复,所以选择unordered_set。需要定义一个多大的数组呢,定一个数组叫做record,大小为26 就可以了,初始化为0,因为字符a到字符z的ASCII也是26个连续的数值。题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要。原创 2023-02-20 22:28:32 · 592 阅读 · 0 评论 -
day4 24. 两两交换链表中的节点 19.删除链表的倒数第N个节点 面试题02.07. 链表相交 142.环形链表II
curA指向链表A的头结点,curB指向链表B的头结点,求出两个链表的长度,并求出两个链表长度的差值,然后让curA移动到和curB 末尾对齐的位置,此时我们就可以比较curA和curB是否相同,如果不相同,同时向后移动curA和curB,如果遇到curA == curB,则找到交点。双指针的经典应用,如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。接下来就是交换相邻两个元素了,此时一定要画图,不画图,操作多个指针很容易乱,而且要操作的先后顺序。原创 2023-02-18 19:14:48 · 971 阅读 · 0 评论 -
day3 203.移除链表元素 707.设计链表 206.反转链表
移除头结点和移除其他节点的操作是不一样的,因为链表的其他节点都是通过前一个节点来移除当前节点,而头结点没有前一个节点。其实可以设置一个虚拟头结点,这样原链表的所有节点就都可以按照统一的方式进行移除了。来看看如何设置一个虚拟头。依然还是在这个链表中,移除元素1。第一种操作:直接使用原来的链表来进行移除。链表操作的两种方式:- 直接使用原来的链表来进行删除操作。- 设置一个虚拟头结点在进行删除操作。第一种操作:直接使用原来的链表来进行移除。移除头结点和移除其他节点的操作是不一样的,因为链表的其他节点原创 2023-02-17 19:57:52 · 1061 阅读 · 0 评论 -
day2 977.有序数组的平方 209.长度最小的子数组 59.螺旋矩阵II
如果A[i] * A[i] >= A[j] * A[j] 那么result[k- -] = A[i] * A[i];如果A[i] * A[i] < A[j] * A[j] 那么result[k- -] = A[j] * A[j];定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置。两个for循环,然后不断寻找符合条件的子序列,时间复杂度为O(n^2)。不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。i指向起始位置,j指向终止位置。每个数平方之后排个序。原创 2023-02-17 10:09:12 · 1170 阅读 · 0 评论 -
day1 704.二分查找 27.移除元素
双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。数组元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组。慢指针:指向更新新数组下标的位置。使用二分法的前提条件:1.有序数组2.无重复元素数组元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。原创 2023-02-15 20:40:30 · 1479 阅读 · 2 评论