自定义博客皮肤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)
  • 收藏
  • 关注

原创 第五周第二天(旅行第二天补卡)|力扣93、复原IP地址 78、子集问题 90、子集问题II

那么就将该字符串保存到结果集中,之前字符串的有效性由自定义函数实现;第三步是确定单层递归的逻辑,单层递归的时候每次要先判断当前切割的字符串的有效性,主要考虑的就是前面注意中的三点,接着如果字符串不合法的话直接结束本层递归就可以了,如果字符串合法的话,那么就要在。

2023-05-04 08:50:20 53

原创 第五周第一天(五一旅行中)|力扣39、组合总和 40、组合总和II 131、分割回文串

思路:组合总和这道题目对于同一个数字允许重复读取,也就是说每次递归的时候不用从原本位置的下一个位置开始递归,仍然用for循环来进行横向遍历,递归来进行纵向遍历,并搭配回溯就可以解决本题,但是这里重点强调一下剪枝的操作,毕竟回溯的效率并不高,因此回溯+剪枝是常见操作,想要剪枝,思路:这题的关键是要学会去重,如果是同一树枝上的,那么重复选取无碍,如果是同一层上的则不可以。

2023-05-02 22:32:32 48

原创 第四周第六天|力扣216、组合总和III 17、电话号码的字母组合

首先我们需要定义一个结果集,还需要定义一个二维数组用来保存结果集,接着我们需要确定回溯函数的返回值及参数,返回值我们说过了,没有特殊情况都是void,至于参数,题目所要求的总和肯定要有吧,我给他命名为targetSum,其次还需要k用来表示组合的个数要求,范围是给定的,此外为了方便比较当前结果集中的总和和目标值的差距,我们设置一个sum表示当前和,再设置一个index用来记录下一次使用搜索开始的位置。补充说明:这里应该如何处理一个数字所对应的字母集呢?我们可以定义一个二维数组来实现。

2023-04-29 14:14:57 59

原创 第四周第五天|回溯法基础、力扣77、组合

我们现在还不知道,在做回溯的时候,我们往往无法一次性写完所有参数,在书写逻辑的时候,缺什么补什么就可以了,现在让我们进行第二部,终止条件的确定,本题终止的条件就是当前结果集中的元素已经达到k个时,我就可以结束递归,保存结果了。思路:对于本题而言,如果用暴力解的话,那么就是用for循环去嵌套遍历了,如果k很大的话那这个循环是没法写的,这个时候我们就可以考虑回溯了,我们需要两个全局变量,一个变量保存结果集,一个变量用二维数组保存各个结果集。细节:首先区分下组合和排列,组合是无序的,排列是有序的。

2023-04-28 16:11:48 41

原创 第四周第四天|力扣669、修剪BST 108、将有序数组转换为BST 538、把BST转换成累加树

如果给我们的是一个数组,那么我们用双指针,一个指针保存前一个节点的数值,另一个指针指向当前节点,这样同时后移就可以实现累加了,BST的处理也是一样的道理,只不过为了处理的方便,我们并不需要保存前一个节点的指针,只需要保存前一个节点的数值就可以了(前一个节点的指针的话可能会操纵空指针,需要特殊化处理)比方说,有一个节点处在我们要保存的范围的左区间外侧,那么它的右子树的所有节点都要比该节点大,我们能保证它的右子树里就没有我们要保存的节点吗?思路:那我们应该怎么做?总结:本题的关键就是要明确什么时候我们才修剪?

2023-04-27 13:46:10 28

原创 第四周第三天|力扣235、BST的最近公共祖先 701、BST中的插入操作 450、删除BST的节点

要删除的节点左右子树都不为空,那么我们要将原子树的左子树移到原子数的右子树的最小节点处,挂在它的左侧,也就是一直想左遍历,遍历到空为止,这就是原子数的左子树的新位置,根据BST的特性,这点应该是可以理解的。思路:本题的关键是要明确根据BST的特性,新加入的节点不管取什么值,最终都会挂在某个叶子节点的下方。要删除的节点左子树为空右子树不为空,那么我们应该返回新的子树的根节点,也就是原子数根节点的右孩子;要删除的节点左子树不为空右子树为空,那么我们应该返回新的子树的根节点,也就是原子数根节点的左孩子;

2023-04-26 16:11:13 25

原创 第四周第二天|力扣530、二叉搜索树的最小绝对差 501、二叉搜索树中的众数 236、二叉树的最近公共祖先

我们可以设出一个变量,这个变量用来存放最小绝对差,题目说了是绝对差,那么当然是一个正数了,通过双指针加上后序遍历,我们可以不断求的有序序列中前一个元素和当前元素的差值,如果得到的差值小于之前保存的差值(初始化为INT_MAX),那么更新这个差值,这样一来,遍历完这棵树的时候,返回这个变量就可以了。其次要清楚,返回公共祖先的几种情况,如果左右指针都不为空,说明各自都找到了一个有效的指针,那么返回根节点(树或者子树的根节点),如果一边为空一边不为空,返回不为空的那一边。//这边程序的执行顺序后面还要再捋一捋。

2023-04-25 20:05:41 24

原创 第四周第一天|力扣654、最大二叉树 617、合并二叉树 700、二叉搜索树中的搜索 98、验证二叉搜索树

思路:合并二叉树,关键是要明确如何处理两颗二叉树,返回值当然是一个根节点的指针了,传入的参数也不难想,就是两颗二叉树的根节点的指针,并且题目已经给我们了,接下来我们就要明确这个合并何时停止,如果一个指针为空,那么我们应该返回另一个指针,对于另外一个指针,也是同样的道理,(注意此处已经包含了两节点都为空时的处理),接下来就是合并了,我们要把两个二叉树的指针同时移动,递归的去处理每一个节点,用前序遍历的方式就好,这部分并没有什么难点,直接给出代码。

2023-04-24 22:25:06 33

原创 第三周第六天(补卡)|力扣513、找树左下角的值 112、路径总和 106、从中序和后序遍历构造二叉树

具体实现的话,首先肯定要有根节点才能去划分呀,所以第一步要先去后序数组找根节点,根据左右中的原则可以知道,在后序数组中,它的最后一个元素就是树的根节点,这里要注意一下,在找根节点之前要先确定中序数组或后序数组不为空,若为空的话直接返回空就好了,若不为空的话再去找根节点,并通过new运算在堆区建立出根节点(如果该节点是叶子节点,直接返回该节点)。分析:这里首先明确本题所说的树的左下角值的含义,它指的是二叉树中最后一行,最左侧节点的数值,因此首先要保证该节点是最后一行才可以,其次要找最后一行的第一个节点。

2023-04-23 18:23:21 28

原创 第三周第五天|力扣222、完全二叉树的节点数量(补上昨天代码)力扣110、平衡二叉树 力扣、257二叉树的所有路径 力扣404、左叶子之和

分析:要求二叉树中所有左叶子节点的和,首先要明确左叶子节点的定义:它指的是当节点A的左孩子不为空,并且节点A的左孩子的左右孩子均为空时,那么节点A的左孩子节点就称为左叶子节点。思路:要想找出一棵树的路径,实际上是要往深处钻,并且既然要求的是路径,那么访问节点的顺序和记录也就是处理节点的顺序应该保持一致,前序遍历就很好的满足这两点,故而可以用前序遍历来记录路径。说明:昨天分析过用完全二叉树的特性这挑一侧进行遍历去进行分析后,代码用的是普通二叉树后序遍历实现的统计,这里再把用完全二叉树特性的代码补上。

2023-04-21 22:17:44 28

原创 力扣第三周第四天|力扣104、二叉树的最大深度 111、二叉树的最小深度 222、完全二叉树的节点数量

明确这点很重要,因为这直接关系到我们对终止条件的设置。

2023-04-20 23:38:30 22

原创 第三周第三天|力扣102、二叉树的层序遍历

思路:之前介绍过二叉树的种类大体可以分为深度优先遍历和广度优先遍历,前中后序遍历都属于深度优先遍历的范畴,而层序遍历则属于图论中广度优先遍历的范畴,对于层序遍历,首先我们先想一想,要想去一层一层的访问节点,我们可以仅仅通过节点的左右指针来实现吗,答案显然是不行的,一层的节点可能有很多,我们只使用左右指针的话是没法去层序遍历的,但是二叉树的结构我们都知道,既然它是一层一层的去遍历,也就意味着它满足先进先出的特点,因此我们可以借助队列这样一种辅助结构来实现二叉树的层序遍历。

2023-04-19 22:44:23 24

原创 第三周第二天|二叉树理论基础 力扣、二叉树的递归遍历

对于前序遍历而言,函数的参数肯定要包括二叉树的节点,和最终前序遍历的结果集,在进行前序遍历的过程中,结果集会按顺序不断收集元素,因此最终不需要返回什么,返回值类型用void即可。二叉树的种类有很多,常见的分类有满二叉树,完全二叉树,二叉搜索树(布局不要求),平衡二叉搜索树(AVL树,左右子树的高度差不能超过1),红黑树(相比于AVL树开销更小,条件更宽松)等等。二叉树不管是在面试中还是实际开发中都有着重要的应用,这部分的内容也相应较多,因此,有一个比较系统的框架才能更好的吸收和掌握这部分的内容。

2023-04-18 19:40:15 26

原创 第三周第一天| 力扣239、 滑动窗口最大值 力扣347、前k个高频元素

既然要使用优先队列,我们就要问,使用大根堆,还是小根堆?总结:这道题目统计频率时使用了map,优先队列的大小为k,综合来看空间复杂度应为O(N),对于时间复杂度,统计频率的时间复杂度为O(n),而不断更新优先队列的过程涉及遍历map以及对小根堆中的元素进行处理,小根堆的本质是一棵有序的完全二叉树,处理其中元素的效率是O(logk),综合来看,时间复杂度应为O(Nlogk),比直接对map进行快排,然后输出结果的时间复杂度O(Nlogn)要好,虽然看上去差不多,但是在n>>k时,差距还是比较明显的。

2023-04-17 20:54:14 31

原创 第二周第六天|力扣20、有效的括号 1047、删除字符串中所有相邻重复项 150、逆波兰表达式求值

这道题目要求输出的结果唯一,以常理来考虑,删除重复项不应该改变字符串的顺序,而栈的特性是先进后出,因此如果用栈的话最后把栈取出来后还要再翻转一下,如果用字符串来模拟栈的话,直接输出字符串就可以了,不需要再翻转,因此本题用string能方便一些。当读取到原字符串中的元素和辅助字符串中的最后一个元素相同时,取出辅助字符串的最后一个元素,当辅助字符串为空或者原字符串的元素和辅助字符串的最后一个元素不同时,将该字符压入辅助字符串中,最后返回辅助字符串即为所求。注意细节:注意字符串的弹出,弹出的是最后一个元素。

2023-04-15 11:14:23 24

原创 第二周第五天|力扣232、用栈实现队列 225、用队列实现栈

第一个栈的作用很明显,可以用来模拟入队,第二个栈就是用来模拟出队的关键了,要想让栈实现先进先出,就得将先进后出的结果再倒回来,因此第二个栈需要将第一个栈的全部,注意是全部数据依次弹出并压入第二个栈,为了方便说明,后面称第一个栈为入栈,第二个栈为出栈,此后只需要将出栈的元素依次弹出即可模拟队列的出队了。判断队空,就是判断两个栈是否全空,全空返回true,否则返回false。思路:这道题目考察的是对栈和队列的理解,栈是先进后出,队列是先进先出,根据这个特性,要想用栈来模拟队列,一个栈是不够的,需要两个栈。

2023-04-14 20:08:07 24

原创 第二周第四天|力扣28、找出字符串中第一个字符的下标 力扣459、重复的子字符串

思路:本题是一道使用kmp算法的经典题,实际上本题所要作的就是字符串的模式匹配,给定一个文本串,一个模板串,要在文本串中找出第一个模板串的位置,并返回其中第一个字符的下标。1、初始化(将前缀末尾用j来表示,初始值设为0,它也代表着最长相等前后缀长度,将后缀末尾用i来表示,它将在for循环中进行初始化(注意其初始值应为1,这是前后缀的定义决定的),如果匹配在第一个字符就失败,无疑要重头匹配,因此next[0]=0)(3)如果j的值等于模式串的尺寸,那么说明匹配成功,返回文本串中第一个字符的下标。

2023-04-13 20:21:37 77

原创 第二周第三天|力扣344、反转字符串 514、反转字符串II 剑指offer05、替换空格 剑指offer58、左旋转字符串

思路:在练习本题之前,复习了数组和链表的相关知识,这是因为字符串的本质可以视为数组,而比较反转链表与反转字符串的区别也很有价值,反转链表也是通过双指针来实现,只不过操纵的是指针,反转字符串虽然也是使用双指针,但是双指针指向的值才是交换的内容,区别还是比较大的。思路:这道题关键是要理清思路,之前做反转字符串II的时候,是先把整体旋转(当然要先做去除空格的操作),再把局部旋转。思路:本题做了些花样,题目要求不但要让反转实现,而且要在指定的区间反转,本题的重点是找到反转区间的规律,在循环反转的表达式上做文章。

2023-04-12 23:13:06 22

原创 训练营第二周第二天|力扣454、四数相加 (巧用map得n^2复杂度) 383、赎金信(类似字母异位词) 15、三数之和(双指针) 18、四数之和(基于三数之和,双指针)

454、四数相加假设:目标数组分别为A\B\C\D分析:本题要求返回一个四元组,该组所有元素求和的结果是0,那么直接的想法就是暴力求解了,时间复杂度会达到O(n^4)这样一个数量级,但是如果能够先对数组AB进行遍历,并用一个容器存储求和的结果以及相同的元素出现的次数(这样做的目的是要满足题目的条件,即重复的结果也算),之后还要在遍历CD的时候通过计算查询该容器是否有出现过想要的值(0-(c+d)),自然想到使用unordered_map,求和的结果作为查询的索引KEY,出现的次数作为valueKEY:

2023-04-11 15:10:39 26

原创 训练营第二周第一天|哈希表的理论基础、力扣 242、有效的字母异位词 349、两个数组的交集(不重复) 202、快乐数 1、两数之和

分析:求不重复的交集,首先交集,就意味着字符的重复出现,考虑使用哈希法来解决,其次数值是分散的,用数组不合适,容易浪费内存空间,因此考虑用集合来解决,multiset首先排除,它允许重复的元素出现,set它的查询效率低于unordered_set,因此最终选用unordered_set容器。KEY:这里容器的选择,首先可以排除数组,理由跟两个数组的交集中相同,如果使用数组,可能造成内存资源的极大浪费,又由于本题要查询的值能够尽快判断是否曾经出现过,因此使用unordered_set来保证查询的效率。

2023-04-10 18:27:57 27

原创 训练营第四天|力扣24、两两交换链表节点(不是值) 19、删除链表倒数第n个节点(双指针) 160、链表相交(双指针) 142、环形链表(双指针)

快指针如果先往前移动n个节点,此后快慢指针同时移动的话,那么当快指针指向nullptr的时候,通过画图可知,慢指针将指向待删除的节点,之前在练习移除链表元素的时候已经分析过,要想移除链表元素,必须找到待删除节点的前一个节点的位置才可以,因此需要将快慢指针间的距离拉大一步,让快指针多往前走一步,然后再通过快慢指针同时移动来使慢指针指向待删除节点的前一个节点的位置。根据上述分析,长链表超出的部分不可能存在相交的指针,因此可以通过求两链表的长度差,让长链表的指针先移动至短链表的头节点的位置,再进行循环比较即可。

2023-04-08 12:33:43 30 1

原创 训练营第三天|力扣203、移除链表元素(虚拟头节点) 707、设计链表 (链表的常见操作) 206、反转链表(双指针)

2、while循环当cur为空时说明链表不存在所要移除的元素,若cur的next是目标元素,那么就要执行移除操作了,值得注意的是,如果使用的是C++的语法,那么为了避免内存泄露,需要手动释放逻辑上被删除的元素,这就需要事先用一个临时指针来保存该元素的位置,这点不要忘了。KEY:指针的反转需要两个指针来配合前移,一定要注意的是,在反转之前,先保存住cur的后继节点的位置,一旦指针反转,该位置不保存的话就再也找不到了。1、虚拟头节点是一个工具节点,它并不是真正的头节点,该节点的next指向真正的头节点。

2023-04-07 20:51:25 159 1

原创 训练营第二天 |力扣 977、有序数组的平方(双指针) 209、长度最小的子数组 (滑动窗口) 59、螺旋矩阵(模拟)

KEY:首先要弄清for循环中的变量用来起什么作用,这点很重要,如果让他指向起始位置,那么另一个指针指向终止位置,通过遍历来不断求解,这又回到了嵌套循环的思路,但是如果让该变量指向终止位置,也就是说让终止位置往前遍历寻找长度最小的子数组,那么另一个指针就可以在终止位置找到满足条件的子数组时向滑动窗口一样往前滑动,从而缩小该子数组的范围,由于从头到尾两个指针只是分别遍历了一遍数组,因此时间复杂度为O(n)。总结:双指针在解决数组类问题时,不管是对于有序数组还是无序数组,都是强大的。

2023-04-06 18:23:56 292 1

原创 算法训练营第一天 /力扣:704 二分查找 、27 移除数组元素

*

2023-04-05 11:11:38 603

空空如也

空空如也

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

TA关注的人

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