算法刷题
文章平均质量分 83
橘子海,
学生一枚 studying~
展开
-
力扣刷题|216.组合总和 III、17.电话号码的字母组合
图中可以看出遍历的深度,就是输入"23"的长度,而叶子节点就是我们要收集的结果,输出[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”]。例如 k = 2,n = 4的话,就是在集合[1,2,3,4,5,6,7,8,9]中求 k(个数) = 2, n(和) = 4的组合。,无非就是多了一个限制,本题是要找到和为n的k个数的组合,而整个集合已经是固定的了[1,…本题就是在[1,2,3,4,5,6,7,8,9]这个集合中找到和为n的k个数的组合。原创 2023-02-20 19:08:28 · 454 阅读 · 0 评论 -
回溯算法理论基础及组合问题
回溯法也可以叫做回溯搜索法,它是一种搜索的方式。回溯是递归的副产品,只要有递归就会有回溯。所以以下讲解中,回溯函数也就是递归函数,指的都是一个函数。原创 2023-02-20 16:23:16 · 280 阅读 · 0 评论 -
力扣刷题|669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树
因为是要遍历整棵树,做修改,其实不需要返回值也可以,我们也可以完成修剪(其实就是从二叉树中移除节点)的操作。因为数组大家都知道怎么遍历啊,从后向前,挨个累加就完事了,这换成了二叉搜索树,看起来就别扭了一些是不是。如果root(当前节点)的元素小于low的数值,那么应该递归右子树,并返回右子树符合条件的头结点。如果root(当前节点)的元素大于high的,那么应该递归左子树,并返回左子树符合条件的头结点。同时需要定义一个全局变量sum,用来保存cur节点的前一个节点的数值,定义为int型就可以了。原创 2023-02-07 11:53:22 · 364 阅读 · 0 评论 -
力扣刷题|235. 二叉搜索树的最近公共祖先、701.二叉搜索树中的插入操作、450.删除二叉搜索树中的节点
如图,我们从根节点搜索,第一次遇到 cur节点是数值在[p, q]区间中,即 节点5,此时可以说明 p 和 q 一定分别存在于 节点 5的左子树,和右子树中。将删除节点(元素7)的左孩子放到删除节点(元素7)的右子树的最左面节点(元素8)的左孩子上,就是把5为根节点的子树移到了8的左孩子的位置。动画中的二叉搜索树中,删除元素7, 那么删除节点(元素7)的左孩子就是5,删除节点(元素7)的右子树的最左面节点是元素8。终止条件就是找到遍历的节点为null的时候,就是要插入节点的位置了,并把插入的节点返回。原创 2023-02-06 19:02:56 · 395 阅读 · 0 评论 -
力扣刷题| 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先
首先最容易想到的一个情况:如果找到一个节点,发现左子树出现结点p,右子树出现节点q,或者 左子树出现结点q,右子树出现节点p,那么该节点就是节点p和q的最近公共祖先。那么我们来说一说,如果 root == q,或者 root == p,说明找到 q p ,则将其返回,这个返回值,后面在中节点的处理过程中会用到,那么中节点的处理逻辑,下面讲解。判断逻辑是 如果递归遍历遇到q,就将q返回,遇到p 就将p返回,那么如果 左右子树的返回值都不为空,说明此时的中节点,一定是q 和p 的最近祖先。原创 2023-02-05 10:18:56 · 408 阅读 · 0 评论 -
力扣刷题|654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树
对于二叉搜索树可就不一样了,因为二叉搜索树的特殊性,也就是节点的有序性,可以不使用辅助栈或者队列就可以写出迭代法。对于一般二叉树,递归过程中还有回溯的过程,例如走一个左方向的分支走到头了,那么要调头,在走右分支。构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。有了这个特性,验证二叉搜索树,就相当于变成了判断一个序列是不是递增的了。其实和遍历一个树逻辑是一样的,只不过传入两个树的节点,同时操作。这就决定了,二叉搜索树,递归遍历和迭代遍历和普通二叉树都不一样。原创 2023-02-03 11:31:32 · 334 阅读 · 0 评论 -
力扣刷题|513.找树左下角的值、112. 路径总和、113.路径总和 ii、106.从中序与后序遍历序列构造二叉树、105.从前序与中序遍历序列构造二叉树
首先回忆一下如何根据两个顺序构造一个唯一的二叉树,相信理论知识大家应该都清楚,就是以 后序数组的最后一个元素为切割点,先切中序数组,根据中序数组,反过来再切后序数组。那么如何找最左边的呢?可以使用前序遍历(当然中序,后序都可以,因为本题没有 中间节点的处理逻辑,只要左优先就行),保证优先左边搜索,然后记录深度最大的叶子节点,此时就是树的最后一行最左边的值。不要去累加然后判断是否等于目标和,那么代码比较麻烦,可以用递减,让计数器count初始为目标和,然后每次减去遍历路径节点上的数值。原创 2023-02-02 14:29:20 · 269 阅读 · 0 评论 -
力扣刷题|110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和
注意,只有当前遍历的节点是父节点,才能判断其子节点是不是左叶子。当遇到左叶子节点的时候,记录数值,然后通过递归求取左子树左叶子之和,和 右子树左叶子之和,相加便是整个树的左叶子之和。然后是递归和回溯的过程,上面说过没有判断cur是否为空,那么在这里递归的时候,如果为空就不进行下一层递归了。此时还没完,递归完,要做回溯啊,因为path 不能一直加入节点,它还要删节点,然后才能加入新的节点。判断一个树的左叶子节点之和,那么一定要传入树的根节点,递归函数的返回值为数值之和,所以为int。原创 2023-01-31 18:26:09 · 199 阅读 · 0 评论 -
力扣刷题|104.二叉树的最大深度、559.n 叉树的最大深度、111.二叉树的最小深度、222.完全二叉树的节点个数
确定单层递归的逻辑:先求它的左子树的深度,再求右子树的深度,最后取左右深度最大的数值 再+1 (加1是因为算上当前中间节点)就是目前节点为根节点的树的深度。确定单层递归的逻辑:先求它的左子树的节点数量,再求右子树的节点数量,最后取总和再加一 (加1是因为算上当前中间节点)就是目前节点为根节点的节点数量。确定递归函数的参数和返回值:参数就是传入树的根节点,返回就返回以该节点为根节点二叉树的节点数量,所以返回值为int类型。在完全二叉树中,如果递归向左遍历的深度等于递归向右遍历的深度,那说明就是满二叉树。原创 2023-01-30 11:23:09 · 298 阅读 · 0 评论 -
力扣刷题|226.翻转二叉树、101. 对称二叉树
对于二叉树是否对称,要比较的是根节点的左子树与右子树是不是相互翻转的,理解这一点就知道了其实我们要比较的是两个树(这两个树是根节点的左右子树),所以在递归遍历的过程中,也是要同时遍历两棵树。这道题目我们也可以使用迭代法,但要注意,这里的迭代法可不是前中后序的迭代写法,因为本题的本质是判断两个树是否是相互翻转的,其实已经不是所谓二叉树遍历的前中后序的关系了。如上代码中,我们可以看出使用的遍历方式,左子树左右中,右子树右左中,所以我把这个遍历顺序也称之为“后序遍历”(尽管不是严格的后序遍历)原创 2023-01-29 11:50:07 · 261 阅读 · 0 评论 -
二叉树的层序遍历
需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。而这种层序遍历方式就是图论中的广度优先遍历,只不过我们应用在二叉树上。层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。本题只是换了一种树,但思路代码都是一样的。原创 2023-01-28 12:37:13 · 771 阅读 · 0 评论 -
力扣刷题| 239. 滑动窗口最大值、347.前 K 个高频元素
可能还会想用一个大顶堆(优先级队列)来存放这个窗口里的k个数字,这样就可以知道最大的最大值是多少了, 但是问题是这个窗口是移动的,而大顶堆每次只能弹出最大值,我们无法移除其他数值,这样就造成大顶堆维护的不是滑动窗口里面的数值了。对于窗口里的元素{2, 3, 5, 1 ,4},单调队列里只维护{5, 4} 就够了,保持单调队列里单调递减,此时队列出口元素就是窗口里最大元素。此时我们需要一个队列,这个队列呢,放进去窗口里的元素,然后随着窗口的移动,队列也一进一出,每次移动之后,队列告诉我们里面的最大值是什么。原创 2023-01-26 13:46:13 · 547 阅读 · 0 评论 -
力扣刷题| 20. 有效的括号、1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值
我们在删除相邻重复项的时候,其实就是要知道当前遍历的这个元素,我们在前一位是不是遍历过一样数值的元素,那么如何记录前面遍历过的元素呢?所以就是用栈来存放,那么栈的目的,就是存放遍历过的元素,当遍历当前的这个元素的时候,去栈里看一下我们是不是遍历过相同数值的相邻元素。从栈中弹出剩余元素,此时是字符串ac,因为从栈里弹出的元素是倒序的,所以再对字符串进行反转一下,就得到了最终的结果。但我们没有必要从二叉树的角度去解决这个问题,只要知道逆波兰表达式是用后序遍历的方式把二叉树序列化了,就可以了。原创 2023-01-25 10:39:30 · 431 阅读 · 0 评论 -
力扣刷题|232.用栈实现队列、225. 用队列实现栈
在push数据的时候,只要数据放进输入栈就好,但在pop的时候,操作就复杂一些,输出栈如果为空,就把进栈数据全部导入进来(注意是全部导入),再从出栈弹出数据,如果输出栈不为空,则直接从出栈弹出数据就可以了。队列模拟栈,其实一个队列就够了,一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时再去弹出元素就是栈的顺序了。使用栈来模式队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈一个输入栈,一个输出栈。如果进栈和出栈都为空的话,说明模拟的队列为空了。原创 2023-01-21 10:16:55 · 63 阅读 · 0 评论 -
力扣刷题|454.四数相加 II、383. 赎金信、15. 三数之和、18. 四数之和
本题是使用哈希法的经典题目,要找到A[i] + B[j] + C[k] + D[l] = 0就可以,不用考虑有重复的四个元素相加等于0的情况。因为题目所只有小写字母,那可以采用空间换取时间的哈希策略, 用一个长度为26的数组还记录magazine里字母出现的次数。其实这道题目使用哈希法并不十分合适,因为在去重的操作中有很多细节需要注意,使用双指针法 要比哈希法高效一些。是一个思路,都是使用双指针法, 基本解法就是在。的基础上再套一层for循环。原创 2023-01-18 13:42:20 · 43 阅读 · 0 评论 -
力扣刷题|344.反转字符串、541. 反转字符串 II、剑指 Offer 05.替换空格、151.翻转字符串里的单词、剑指 Offer58-II.左旋转字符串
看到这个题目要求,我首先想到的是用StringBuilder来实现,遍历字符串通过判断来决定StringBuilder中加入什么。这道题目还是比较简单的,我们可以定义两个指针,分别指向数组的两端,两个指针同时向中间移动并交换元素。本题要求是反转每2k个字符的前k个字符,我们只需要让下表每次向前移动2k个即可。举个例子,源字符串为:"the sky is blue "然后这道题也可以使用双指针法来完成,具体实现方法如下图。原创 2023-01-18 11:48:49 · 43 阅读 · 0 评论 -
力扣刷题|242.有效的字母异位词、349. 两个数组的交集、202. 快乐数、1. 两数之和
在遍历数组的时候,只需要向map去查询是否有和目前遍历元素比配的数值,如果有,就找到的匹配对,如果没有,就把目前遍历的元素放进map中,因为map存放的就是我们访问过的元素。因为本题,我们不仅要知道元素有没有遍历过,还有知道这个元素对应的下标,需要使用 key value结构来存放,key来存元素,value来存下标,那么使用map集合正合适。输出结果中的每个元素一定是唯一的,也就是说输出的结果的去重的, 同时可以不考虑输出结果的顺序,那我们可以使用set集合来存储数组中的数据。原创 2023-01-16 21:51:09 · 121 阅读 · 0 评论 -
力扣刷题|24. 两两交换链表中的节点、19.删除链表的倒数第 N 个节点、面试题 02.07. 链表相交、142.环形链表 II
创建一个结点cur,cur的下一个结点指向要交换的两个结点的第一个结点 创建firstnode和secondnode分别用来存储要交换的两个结点的第一个结点和第二个结点 创建一个temp结点指向下一次要交换的两个结点的第一个结点 步骤一:让cur的下一个结点指向secondnode步骤二:让secondnode的下一个结点指向firstnode原创 2023-01-15 10:34:25 · 76 阅读 · 0 评论 -
力扣刷题|203.移除链表元素、707.设计链表、206.反转链表
反转链表:1. 定义一个pre结点指向,pre的下一个结点指向head2. 定义一个cur结点指向head3. 定义一个temp结点指向head4. 循环内首先让temp结点移动到下一个结点5. 让cur的下一个结点指向pre6. pre移动到下一个结点7. cur移动到下一个结点8. 循环完成让head的下一个结点指向null,返回pre即为反转后的链表原创 2023-01-13 11:17:45 · 61 阅读 · 0 评论 -
力扣刷题|977.有序数组的平方 、209.长度最小的子数组 、59.螺旋矩阵
LeetCode 977.有序数组的平方,数组平方的最大值在数组的两端,而且都是向中间逐渐递减的这里采用双指针法,m指向起始位置,n指向结束位置定义一个result的新数组大小和原数组相同,k指向数组的末尾比较m指向的位置和n指向的位置的数据的平方的大小,较大的存入k指向的位置并把该指针向数组中间方向移动代码实现时间复杂度:O(n)LeetCode。原创 2023-01-12 16:11:42 · 200 阅读 · 0 评论 -
力扣刷题|704. 二分查找、27. 移除元素
二分法涉及到挺多的边界问题,首先就是要定义好区间,区间的定义就是不变量区间的定义一般为两种,左闭右闭即[left, right],或者左闭右开即[left, right)。 二分查找的前提条件数组为有序数组 移除元素,数组中没有重复元素数组在内存空间的地址是连续的,删除其实就等于覆盖主要有两种方法:暴力解法:两层for循环,一是循环遍历数组元素,二是循环更新元素,双指针法:定义快慢指针,在一个for循环下完成遍历原创 2023-01-12 11:09:51 · 229 阅读 · 0 评论