自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 501.二叉搜索树中的众数

给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。例如:给定 BST [1,null,2,2],返回[2].提示:如果众数超过1个,不需考虑输出顺序进阶:你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)思路:注:如果不是二叉搜索树,而是普通二叉树,方法为:先把树全部遍历一遍,用什么顺序遍历都可以,统计元素频率,把统计出来的出现频率(map中的value排序)。二叉搜索树:双指针,中序遍历。

2024-06-10 23:45:28 469

原创 530.二叉搜索树的最小绝对差

(暴力方法)因为二叉搜索树的元素是有序的,可以把元素放入一个list,然后计算list中相邻两元素的差值,找到最小的差值。如果pre不是None,把result更新为result和cur.val-pre.val的较小的值。然后让pre=cur。给你一棵所有节点为非负值的二叉搜索树,请你计算树中任意两节点的差的绝对值的最小值。的功能是找到二叉搜索树中任意两节点值之间的最小差值。的功能是找到二叉搜索树中任意两节点值之间的最小差值。(更好的方法)中序遍历,双指针,直接得出最小绝对差。两个指针:pre,cur。

2024-06-09 23:38:03 482

原创 98.验证二叉搜索树

因为是按照中序遍历:左中右,所以遍历过程中,每一个遍历到的值,都应该比之前遍历的值中的最大值更大。所以,如果当前节点的值不大于self.maxVal,说明树不是有效的BST,return False。方法一:先把二叉树遍历下来,再判断是否是从小到大有序的。(这不是最优的方法,其实没必要把元素都存下来,直接在遍历二叉树的时候就可以判断是否单调递增)二叉搜索树:左子树的所有节点都小于根节点,右子树的所有节点都大于根节点。二叉搜索树:中序遍历(左中右),元素是有序的!递归法(版本二):设定极小值,进行比较。

2024-06-09 02:13:56 508

原创 700.二叉搜索树中的搜索

对于二叉搜索树可就不一样了,因为二叉搜索树的特殊性,也就是节点的有序性,可以不使用辅助栈或者队列就可以写出迭代法。对于一般二叉树,递归过程中还有回溯的过程,例如走一个左方向的分支走到头了,那么要调头,在走右分支。搜索的时候,如果值比root小,就去遍历左子树;在上述示例中,如果要找的值是 5,但因为没有节点值为 5,我们应该返回 NULL。二叉搜索树:根节点的值比左子树的所有节点的值都大,比右子树的所有节点的值都小。这就决定了,二叉搜索树,递归遍历和迭代遍历和普通二叉树都不一样。例如要搜索元素为3的节点,

2024-06-08 01:48:28 760

原创 617.合并二叉树

当一个树的节点为空,而另一个树的节点不为空时,代码会返回非空的那个节点及其子树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。反之,如果t2为None,那两个树合并就是t1(如果t1也是None也没关系,那合并之后就是None)要合并两个二叉树,参数要穿入两个二叉树的根节点,返回值就是合并之后二叉树的根节点。其实和遍历一个树的逻辑是一样的,只不过传入两个树的节点,同时操作。传入了两个树,有两个树遍历的节点t1和t2。

2024-06-07 02:19:25 659

原创 654.最大二叉树

给定一个不含重复元素的整数数组。通过给定的数组构建最大二叉树,并且输出这个树的根节点。给定的数组的大小在 [1, 1000] 之间。构造二叉树,一定用前序遍历(中左右)

2024-06-06 00:53:09 302

原创 106.从中序与后序遍历序列构造二叉树

但是前序和后序不能确定二叉树,因为左和右分不开,不知道从哪里分开。从后序遍历中找到“中”节点,再在中序遍历中,切割。5. 切割后序数组(按照中序数组切割出来的,来分)根据一棵树的中序遍历与后序遍历构造二叉树。中序和后序、前序和中序,都可以确定二叉树。注意: 你可以假设树中没有重复的元素。后序遍历,最后一个元素一定是根节点。2. 后序数组最后一个元素为节点元素。3. 寻找中序数组位置作切割点。1. 后序数组为0,那就是空。6. 递归处理左区间和右区间。

2024-06-04 23:43:24 722

原创 112. 路径总和

往下遍历,每遍历到一个节点,就减掉这个节点的值。如果这条路径遍历到叶子结点,所剩的值还不是0,那就说明这条路径不对,回溯,每回溯一个节点就加上对应的值,再去遍历其他路径。给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。这是一个递归函数,用于遍历二叉树并检查是否存在从根节点到叶子节点的路径,使路径上所有节点值的和等于给定的。这是主函数,用于判断给定的二叉树是否存在路径,使路径上所有节点值的和等于给定的。说明: 叶子节点是指没有子节点的节点。

2024-06-03 23:59:06 546

原创 513.找树左下角的值

优先左边搜索,记录深度最大的叶子节点,此时就是树的最后一行最左边的值。给定一个二叉树,在树的最后一行找到最左边的值。深度最大的叶子结点一定是最后一行。

2024-06-02 23:04:18 537

原创 404.左叶子之和

通过父节点来判断七子节点是不是我们要收集的元素。因为如果遍历到孩子节点,我们无法判断它是左孩子还是右孩子。如果该节点的左节点不为空,该节点的左节点的左节点为空,该节点的左节点的右节点为空,则找到了一个左叶子。计算给定二叉树的所有左叶子之和。

2024-06-01 22:15:43 428

原创 257. 二叉树的所有路径

给定一个二叉树,返回所有从根节点到叶子节点的路径。说明: 叶子节点是指没有子节点的节点。

2024-05-31 10:16:34 576

原创 110.平衡二叉树

本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。给定二叉树 [1,2,2,3,3,null,null,4,4]给定二叉树 [3,9,20,null,null,15,7]给定一个二叉树,判断它是否是高度平衡的二叉树。返回 false。

2024-05-30 10:26:35 426

原创 222.完全二叉树的节点个数

2. 最后一层不满,分别递归左右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后就按照情况1来计算。完全二叉树就是,除了最后一层可能没有填满之外,上面的层一定都是填满的。最后一层从左到右,都集中在左边。首先,一直向左和一直向右遍历,如果深度相等,就是满二叉树,否则不是满二叉树。1. 最后一层也是满的,那么节点数量就是2^树深度-1。给出一个完全二叉树,求出该树的节点个数。

2024-05-29 10:16:45 473

原创 111.二叉树的最小深度

【中】【注意这里和最大高度不同点:最大高度就是取左右子树的最大值,但是这里不能这样,如果左边为None,右边有值,那么就 return 1+右边子树的最小高度。剩下一种情况:左右子树都不为空,return 1+min(左子树最小高度,右子树最小高度)同理,如果左子树不为空,右子树为空,那么return 1+左子树最小高度。先确定递归的终止条件:遇到空节点,此时高度为0,return 0。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。说明: 叶子节点是指没有子节点的节点。返回它的最小深度 2.

2024-05-28 09:29:45 505

原创 104.二叉树的最大深度

示例: 给定二叉树 [3,9,20,null,null,15,7],二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明: 叶子节点是指没有子节点的节点。给定一个二叉树,找出其最大深度。返回它的最大深度 3。

2024-05-27 10:25:04 336

原创 101. 对称二叉树

如果是前序(中左右)或者中序(左中右),处理到中间节点的时候,还没有处理完孩子节点,信息不全。然后,else,就是当前 left.val == right.val,那么做下一层的判断。此时才进入单层递归的逻辑,单层递归的逻辑就是处理 左右节点都不为空,且数值相同的情况。然后判断以根节点的左孩子为根节点的信息,和根节点的右孩子为根节点的信息,进行比较。判断左右两颗子树是否对称,一棵树遍历顺序为 左右中,另一棵树遍历顺序为 右左中。【收集左右孩子的信息,向上一层返回,都是用后序遍历】

2024-05-25 20:28:02 427

原创 226.翻转二叉树

中序遍历不可以,因为如果是左中右,先对左子树使用交换函数,然后交换左右子树,然后对右子树使用交换函数(但是此时的右子树是之前的左子树,已经处理过了),但是如果这时继续还是处理左子树,那是可以的,相当于处理了原来的右子树。用后序遍历也可以,就是先分别对左右孩子用交换函数,然后把“中”的左右孩子交换顺序。然后分别对它的左孩子和右孩子使用“交换函数”(定义的)(递归)遍历到“中”的时候,交换它的左右孩子。用递归(前序or后序,中序不行)

2024-05-24 21:00:52 556

原创 【详细讲解】二叉树的层序遍历

加入元素,记录size,size就是当前这一层的元素个数。不断弹出元素,size -= 1, 同时加入弹出元素的左右孩子,直到size==0,说明当前层已经完全遍历完,然后让size=queue里面的元素个数,就是下一层一共有多少个元素,重复上述步骤。直到size==0且queue中没有元素了,就遍历完成了。117.填充每个节点的下一个右侧节点指针II。116.填充每个节点的下一个右侧节点指针。102.二叉树的层序遍历。637.二叉树的层平均值。104.二叉树的最大深度。111.二叉树的最小深度。

2024-05-23 19:39:45 538

原创 【详细讲解】二叉树的统一迭代法

上篇文章讲到了用迭代实现递归,但是中序遍历和前、后序遍历非常不同,那么有没有统一的方法呢?这种方法也可以叫做标记法。在“中”的后面加空指针。

2024-05-22 22:33:40 493

原创 【详细讲解】二叉树的迭代遍历 144,145,94

把上面的前序,左右颠倒顺序(先放左孩子,再放右孩子,入stack),变成了中右左,然后,再把整个数组做翻转(双指针法,也可以用库函数reverse直接反转),变成左右中。先把root放入stack,弹出这个元素,然后,把它的右孩子先放入stack,然后把它的左孩子放入stack。然后,弹出左孩子,然后看这个左孩子的左右孩子,先把它的右孩子放入stack,再把它的左孩子放入stack。【注意,是右孩子先入stack,左孩子之后才入stack,这样弹出的时候,才会先弹出左孩子!2. 输出的结果要倒序】

2024-05-21 21:09:33 636

原创 【详细讲解】二叉树的递归遍历 144,145,94

2. 确定终止条件:写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。1. 确定递归函数的参数和返回值:确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。3. 确定单层递归的逻辑:确定每一层递归需要处理的信息。先把根节点加入,然后遍历左子树,还是用同样的逻辑去遍历,所以可以用递归函数。

2024-05-20 21:05:50 353

原创 【详细讲解知识点】二叉树

leetcode题目中一般都给定义好了,但是还是要掌握是怎么写定义的,面试的时候有可能会考察写出二叉树的定义。2. 完全二叉树 除了底层以外 其他层都是满的 底层:从左到右节点连续。若左子树不为空,则左子树上所有节点的值都小于它的根节点的值。若右子树不为空,则右子树上所有节点的值都大于它的根节点的值。【记忆技巧:前中后指的是中间节点的遍历顺序】(1)前序遍历(递归法,迭代法) 中左右。(2)中序遍历(递归法,迭代法) 左中右。(3)后序遍历(递归法,迭代法) 左右中。(1)层次遍历(迭代法)

2024-05-19 21:51:05 414

原创 347.前 K 个高频元素

每次调用 heapq.heappush,新的元素都会被插入到堆中,同时堆的结构会被调整,以确保最小元素始终在堆顶。heapq.heappush 是 Python 标准库 heapq 模块中的一个函数,用于将一个新的元素添加到堆中,同时保持堆的性质。这里我们使用小顶堆,因为顶堆每次push新元素进来之后,会把父元素弹出去,我们像找到最大的k个元素,就要用小顶堆。这里面的“1”代表的是,弹出堆顶元素(是一个对,第0个元素是出现次数,第1个元素是数值)并且取其第1个元素。小顶堆:父元素小,子元素大。

2024-05-18 21:23:35 338

原创 239. 滑动窗口最大值

push方法:在向queue中添加新元素之前,先检查queue的尾部的元素是否有比新元素小的元素,如果有,就把所有比新元素小的元素都弹出,然后再把新元素加入queue,保证queue中的元素都是从大到小排序的。如果新加进来的元素比前面的所有元素都大,那就把前面所有的元素都弹出去。pop方法:先检查queue是否为空,然后检查queue的头部元素是否为滑动窗口最左边的元素,如果是,就弹出。(因为queue中的元素从大到小排序,queue的头部元素不一定是滑动窗口的头部元素)返回滑动窗口中的最大值。

2024-05-18 07:46:38 498

原创 150. 逆波兰表达式求值

也就是,key对应四个运算符的写法,其对应的value是真正的运算符号。输入: ["10", "6", "9", "3", "+", "-11", " * ", "/", " * ", "17", "+", "5", "+"]看到运算符,就取出stack尾部的2个元素,根据运算符来进行相对应的运算,然后把运算结果加入stack。平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 )。该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * )。

2024-05-17 00:04:21 730

原创 1047. 删除字符串中的所有相邻重复项

注意,if statement中,先检查res是否为None,然后再看res[-1]==i,否则,直接调用res[-1], 如果res为None,就会报错。如果stack中尾部元素和遍历到的元素一样,就把stack的尾部元素弹出去。遇到”消消乐“的这种题(比如,括号匹配,删除连续的相同的两个元素),尤其是,消除一对之后,还要看新的字符串是否还有继续可以匹配的一对,这种情况用stack就非常合适。给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。这道题还是比较简单的。

2024-05-15 22:50:19 449

原创 20. 有效的括号

如果看到右括号,就弹出stack中最后进入的那个左括号,和右括号比较看是否匹配。如果匹配,那就继续这个过程,看到左括号就加入stack,看到右括号就弹出stack中最后一个左括号进行比对。可以在看到左括号的时候,直接把这个左括号对应的右括号加入stack,这样,在看到右括号的时候,就可以直接从stack中弹出并且进行比较,不需要再转换了。给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。2. 有不匹配的左右括号:遍历的时候,弹出,发现不匹配。

2024-05-14 21:37:48 552

原创 225. 用队列实现栈

上一题我们用了两个stack,一个stack_in,一个stack_out,来实现queue,思路是,queue是先进先出,stack是先进后出,所以我们需要第二个stack来存储第一个stack里的元素,从而可以让stack里面先进去的元素先出来。但是这道题是用queue实现stack,queue是先进先出,所以我们可以先让queue前面的元素出来,把它们放进queue的末尾,然后把queue原本末尾的元素取出来。只要把前面的元素加入到queue的后面就可以了。用一个queue就可以实现。

2024-05-13 21:33:40 309

原创 232.用栈实现队列

第二个stack,当pop元素的时候,我们先判断第二个stack是否为空,为空,就把第一个stack里的元素pop出来,push进第二个stack,再从第二个stack里pop元素出来。这个时候pop出来的元素就是第一个stack里最先进入的元素。如果第二个stack不为空,那就直接pop第二个stack尾部的元素即可。判断queue是否为空:如果两个stack都为空,那么queue就为空了。push(x) -- 将一个元素放入队列的尾部。peek() -- 返回队列首部的元素。

2024-05-12 21:22:35 403

原创 459.重复的子字符串

给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。例子:ababab,最长相等前后缀是abab,不包含ab,那么重复子串(如果有的话)是ab。如果一个字符串可以由重复子串构成,那么这个子串 是 它的最长相等前后缀 不包含的部分。KMP算法还需要多看,多联系,去熟练。这道题思路比较巧妙。

2024-05-11 21:57:33 509

原创 【KMP算法最详细讲解】28. 实现 strStr()

其中n为文本串长度,m为模式串长度,因为在匹配的过程中,根据前缀表不断调整匹配的位置,可以看出匹配的过程是O(n),之前还要单独生成next数组,时间复杂度是O(m)。所以整个KMP算法的时间复杂度是O(n+m)的。相当于是,我们发现f这个位置不匹配了,但我们之前f前面的aa,和子串的前两位aa,是一样的,所以子串从它后两位aa对应的长串的位置,重新看aa后面的b与长串aa的后面是不是对应就可以了。前缀表是用来回退的,它记录了当模式串与主串不匹配的时候,模式串应该从哪里和主串重新匹配。

2024-05-10 23:21:15 916

原创 卡码55. 右旋字符串

字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。先把字符串整体倒序,这样,现在的前面k个字符就是之前的后k个字符,现在的后(n-k)个字符就是之前的前(n-k)个字符。s[len(s)-k:]表示的是,从位置len(s)-k开始,也就是从倒数第k个位置开始,一直到s的末尾。s[:len(s)-k]表示的是,从s的头开始,一直到len(s)-k-1个元素的位置。

2024-05-09 20:58:01 272

原创 151.翻转字符串里的单词

(注意:其实如果使用库函数,可以直接split,拆成一个个单词,再把单词倒序放入新的list,再变成str,但是这样就起不到练习题的效果了,所以这里不用这种简单的方法)注意,strip()函数并不直接改变原来的str,而是生成新的str。但是这道题似乎不需要先用strip函数删除前后空白,因为s.split()就是把单词拿出来,放入list,前后的空格就没有了。先不管每个单词中字母的顺序是否是正确的,我们先让单词与单词之间的相对位置都是正确的。输出: "example good a"输出: "world!

2024-05-08 22:25:33 547

原创 卡码54. 替换数字

给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。当left遇到数字,就把number按照从后往前的顺序,加入新数组,right逐步减1. 然后left-=1。当left遇到字母,就把它放到新数组right的位置,right-=1,left-=1。遍历list中的元素,一旦遇到数字,就把它变成‘number’

2024-05-08 21:27:45 592

原创 541. 反转字符串II

比如,最后如果还有3个元素,但是k=5,我们要求对(n-3,n+1)元素进行操作,但是只有(n-3,n-1), 也没关系,不会报错,只是会对(n-3,n-1)的元素进行操作。给定一个字符串 s 和一个整数 k,从字符串开头算起, 每计数至 2k 个字符,就反转这 2k 个字符中的前 k 个字符。注意:str是不可变的!注意,python中,如果可操作的元素数量不足,也没关系,会对这些元素进行操作。遍历s,每2k个元素,对前k个元素进行反转子字符串的操作。输入: s = "abcdefg", k = 2。

2024-05-07 20:55:17 302

原创 344.反转字符串

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。left,right先指向head和tail,交换,然后两个指针同时往中间移动。题目要求时间复杂度是O(1),就是要原地进行操作,不要去申请新的list。输入:["H","a","n","n","a","h"]输出:["h","a","n","n","a","H"]输入:["h","e","l","l","o"]输出:["o","l","l","e","h"]有了双指针的思路之后,代码其实很简单。

2024-05-07 20:07:25 242

原创 18. 四数之和

示例: 给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。满足要求的四元组集合为: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ]固定i和j,用两个for loop,做剪枝操作注意要求target>0才可以判断nums[i]>target或者判断nums[i]+nums[j]>target。其他操作和三数之和差不多,固定了i和j之后,也是用left和right两个指针去找四数之和=target。

2024-05-06 23:25:37 410

原创 15. 三数之和

【注意】判断是否相同元素的时候,不能判断nums[i]是否等于nums[i+1],因为,结果集里面是可以有重复的元素的。如果你要判断nums[i]是否等于nums[i+1],相当于让结果集里不能有重复的元素,这是不对的。判断nums[left]是否等于nums[left-1], nums[right]是否等于nums[right+1]先固定a, a是nums[0], 然后,left指针指向a右边的第一个元素,right指针指向nums末尾的元素。应该判断nums[i]是否等于nums[i-1]

2024-05-06 22:13:14 684

原创 383. 赎金信

给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串 ransom 能不能由第二个字符串 magazines 里面的字符构成。(题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。杂志字符串中的每个字符只能在赎金信字符串中使用一次。创建字典dict,遍历ransom,把ransom出现的字母存入dict的key,字母出现的次数为对应的value。遍历magazine,如果字母在dict中没有出现,就不管。否则,就是False。

2024-05-05 23:18:14 138 2

原创 454.四数相加II

为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500。给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。遍历c和d,如果0-(c+d)在dict中出现过,就把count+= (a+b)对应的value。第一个if statement: 如果i+j不在res,则res[i+j]=1,而不是=0。定义count=0,用来统计个数。

2024-05-05 21:53:54 192 2

空空如也

空空如也

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

TA关注的人

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