自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 LeetCode刷题合集

在添加左括号时,只有当已添加的左括号数量小于 n 时,才可以添加一个左括号。这确保了左括号不会超过它们的总数。与上一题是一样的思路。由于删除后,重复元素只出现一次,因此头节点不需要删除,无需 dummy_head。与上一题不同的是,这次我们需要完全删除所有重复元素。因此我们定位到要删除元素的前一个节点。:在添加右括号时,只有当已添加的右括号数量小于已添加的左括号数量时,才可以添加一个右括号。与上一题不同的是,本题的输入为数组,每个字符都是一个元素。和112的区别是,需要记录路径。

2024-04-23 20:46:41 1622

原创 面试手撕合集

定义单个指针,指向虚拟头节点。如果,说明后面的两个节点重复,例如后面存在。我们令->,实现删除两个的操作。利用矩阵的递增性质:从左下角元素开始搜索,同列元素都小于此元素,同行元素都大于此元素。因此和比较后,我们可以立即排除一行或者一列的元素。从右上角开始同理,这是由于这两处的元素大小处在所在行和列的所有元素中间,可以利用缩减搜索规模。而左上和右下角的元素处在所在行和列的所有元素的两端。

2024-04-15 17:33:09 904

原创 代码随想录|Day35|动态规划04|01背包(二维、一维)、416.分割等和子集

的背包所能装入的最大价值。关键在于更新这个数组时需要从后往前更新,这样可以保证在更新。仍然代表没有考虑当前物品时的状态。使用一维数组时,数组的每个元素。表示对于当前考虑的物品,容量为。背包能背的物品最大价值是?

2024-04-08 23:54:05 688

原创 代码随想录|Day34|动态规划03|343.整数拆分、96.不同的二叉搜索树

所以dp[3] = dp[2] * dp[0] + dp[1] * dp[1] + dp[0] * dp[2]因此,dp[3] = 以1为头节点的搜索树数量 + 以2为头节点的搜索树数量 + 以3为头节点的搜索树数量。有2个元素的搜索树数量就是dp[2]。有1个元素的搜索树数量就是dp[1]。有0个元素的搜索树数量就是dp[0]。

2024-04-08 17:55:19 666

原创 代码随想录|Day33|动态规划02|62.不同路径、63.不同路径II

【代码】代码随想录|Day33|动态规划02|62.不同路径、63.不同路径II。

2024-04-05 19:43:58 366

原创 代码随想录|Day32|动态规划01|509.斐波那契数列、70.爬楼梯、746.使用最小花费爬楼梯

对于3阶,可以从1阶或者2阶爬1次到达,也就是说3阶 = 1阶 + 2阶 = 1 + 2 = 3。3阶:3种:1台阶3次;1台阶1次+2台阶1次;2台阶1次+1台阶2次。2阶:2种:1台阶2次;

2024-04-05 16:05:51 475

原创 代码随想录|Day31|贪心06|738.单调递增的数字

从字符串的最后一位向前遍历,即从低位到高位进行检查。这是因为当我们修改某一位数字时,可能会影响到更低位的数字。

2024-04-04 22:24:12 404

原创 代码随想录|Day30|贪心05|435.无重叠区间、763.划分字母的区间、56.合并区间

算法首先遍历整个字符串,为每个字符记录下它在字符串中最后一次出现的索引位置。这一步是关键,因为要确保一个片段包含了其所有字符的所有出现,这个片段就必须延伸到每个字符的最后出现位置。

2024-04-04 00:55:23 583

原创 代码随想录|Day29|贪心04|860.柠檬水找零、406.根据身高重建队列、452.用最少数量的箭引爆气球

思路:按照左边界对数组进行排序,通过判断当前气球的左边界 是否大于 上一个气球的右边界来判断是否重叠。需要注意的是,存在2个甚至更多气球重叠的情况,因此每次发现重叠气球的情况时,我们需要寻找一个最优的射击位置:重叠气球中最小的右边界。因为10元只能用来给20元账单找零,而5元既可以给20元或10元账单找零。如果账单是20,应该优先消耗一个10元一个5元,而不是三个5元。5元更万能,因此使用贪心策略,优先消耗10元,可以给更多的账单找零。的人,因此更高的应该排在前面,我们按照身高。对于身高相同的人,按照。

2024-03-31 22:01:33 344

原创 代码随想录|Day28|贪心03|1005.K次取反后最大化的数组和、134.加油站、135.分发糖果

思路:我们可以计算 每个加油站的剩余量。中的所有加油站都不能作为起始点。,开始累加每个加油站的。

2024-03-30 02:24:18 346

原创 代码随想录|Day27|贪心02|122.买卖股票的最佳时机II、55.跳跃游戏、45.跳跃游戏II

思路:同样是计算每一步的覆盖范围,在此覆盖范围内,如果无法到达末尾,则需要启用下一个范围,并且是最大范围(因为我们寻找最少跳跃步数)跳跃数+1。如下图所示,最大利润这样获得:第二天买,第四天卖,第五天买,第六天卖。要实现最大利润,可以每天都进行买卖,只收集正利润的天数。遍历数组,我们维护一个 最大范围,只要最大范围能过覆盖到数组末位,则说明可以到达最后一个位置。的区别是一定可以跳跃到末尾,但需要计算最少跳跃步数。

2024-03-24 22:47:34 369

原创 代码随想录|Day26|贪心01|455.分发饼干、376.摆动序列、53.最大子数组和

表示如果序列在当前点结束并且最后一次摆动是上升的,那么摆动序列的最长长度是多少。每当我们发现一个元素比前一个元素大,就意味着我们可以在之前的下降摆动序列的基础上增加一个上升摆动,因此。:表示如果序列在当前点结束并且最后一次摆动是下降的,那么摆动序列的最长长度是多少。每当我们发现一个元素比前一个元素小,就意味着我们可以在之前的上升摆动序列的基础上增加一个下降摆动,因此。对于胃口最大的小孩,我们查看最大的饼干能否满足,如果不能,则说明此小孩无法被满足,无需查看其他更小的饼干,直接判断胃口稍微小一点的小孩。

2024-03-24 16:20:43 336

原创 牛客笔试|美团2024春招第一场【测试方向】

小美拿到了一个由正整数组成的数组,但其中有一些元素是未知的(用 0 来表示)。现在小美想知道,如果那些未知的元素在区间 [l, r] 范围内随机取值的话,数组所有元素之和的最小值和最大值分别是多少?共有 q次 询输入描述:第一行输入两个正整数 n, q ,代表数组大小和询问次数。第二行输入 n 个整数。接下来的 q 行,每行输入两个正整数 l, r,代表一次询问。输出描述:输出 q 行,每行输出两个正整数,代表所有元素之和的最小值和最大值。示例:输入例子:3 21 0 3。

2024-03-22 23:42:19 4692

原创 代码随想录|Day25|回溯05|491.非递减子序列、46.全排列、47.全排列II

本题多了一个存在重复数字的条件,因此为了确保同一元素不被重复选取,采用上一题的方法并不行。因为我们只是不能取同一元素,但如果两个元素的值相同呢?虽然题目没有明确不能排序,但如果排序了,集合本身就是递增子序列,这是LeetCode示例2中没有出现的。所以本题的关键在于,如何在不排序的情况下对树层去重。在树层遍历的时候(也就是for循环),我们维护一个。排列问题和组合问题的区别在于,顺序不同算作不同排列。在组合问题中,我们定义。在排列问题中,我们不再需要。数组,记录已经使用过的元素。

2024-03-20 15:47:43 417

原创 代码随想录|Day24|回溯04|93.复原IP地址、78.子集、90.子集II

和 上一题 78.子集 的结合。如果集合中出现重复元素,则需要进行 树层去重。一样是一个切割问题,我们使用回溯来遍历所有情况,然后判断IP是否合法。如果把 子集问题、组合问题、分割问题都抽象为一棵树的话,

2024-03-19 15:47:23 256

原创 代码随想录|Day23|回溯03|39.组合总和、40.组合总和II、131.分割回文串

中的元素可能重复,如果使用传统的方法递归,则结果很有可能包含重复组合。本题可以理解为一个组合问题,我们组合不同的元素,判断是否为回文子串。也是符合条件的,如果排序则可以确保接下来搜索的元素更大,换句话说。举个例子,假设总和为。符合条件,下一次搜索可能获得。一定会更大,在此之前判断。排序,那么下一层递归的。剪枝:如果我们事先对。的判断可以实现剪枝。,此时出现了重复组合。

2024-03-18 22:38:01 377

原创 代码随想录|Day22|回溯02|216.组合总和III、17.电话号码的字母组合

由于每个数字对应的字母都没有重复,因此每个结果都符合题意,不需要剪枝。本题相当于从每个数字对应的字母中构建结果,我们需要借助一个。类似,在此基础上多了一个和为。

2024-03-16 22:33:50 422

原创 代码随想录|Day21|回溯01|77.组合

为树的深度,回溯的本质依然是暴力解法,只是不需要显式写出嵌套循环而已,而是用递归代替。具体的操作很简单,只需要修改递归终止条件即可。我们考虑回溯,可以将组合问题看作一棵树,可以很容易写出暴力解法。为取数的范围,每个组合包含。的值过大,代码将会非常冗长。组合问题不考虑顺序,例如。元素数量,所以我们嵌套。,那么在元素不足以凑齐。

2024-03-16 15:33:04 617 1

原创 代码随想录|Day20|二叉树09|669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树

思路:我们知道,按照中序遍历一个二叉搜索树将获得一个递增数组。因此我们可以将数组二分,中间元素所谓根节点,左边元素作为左子树,右边元素作为右子树,递归下去可以构成平衡二叉搜索树。指在二叉搜索树(BST)的基础上进行转换得到的一种特殊形式的树。在累加树中,每个节点的值被替换为原始二叉搜索树中所有大于该节点值的节点值之和加上该节点自身的值。思路:我们从最大值开始累加,因此遍历顺序是元素从大到小。我们可以使用反向中序遍历来实现:右中左。

2024-03-15 23:04:33 517 1

原创 代码随想录|Day19|二叉树08|235. 二叉搜索树的最近公共祖先、701.二叉搜索树中的插入操作、450.删除二叉搜索树中的节点

可以看到,向搜索树添加元素很简单,因为不需要改变树的结构,而删除节点则需要改变结构。

2024-03-13 16:38:21 571

原创 代码随想录|Day18|二叉树07|530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先

思路:利用二叉搜索树的特性,同样是在遍历过程中统计每个元素出现的频率,并维护一个最大频率。由于我们需要完整遍历整个树才能确切知道最大频率,因此这里采取这样的措施:如果当前记录的最大频率被更新,则清空已收集的元素,重新收集。的逻辑类似,由于二叉搜索树的特性,中序遍历的结果将是单调递增的,最小绝对差一定发生在遍历的相邻节点。思路2:中序遍历的过程中,计算相邻遍历节点的绝对差,维护一个最小绝对差。思路1:中序遍历二叉搜索树,得到一个单调递增的数组,接着从中寻找最小绝对差。,指向当前节点的前一节点。

2024-03-12 23:39:41 371 1

原创 代码随想录|Day17|二叉树06|654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

首先回顾一下二叉搜索树的定义:对于任意节点,其左子树中的所有节点都小于该节点,右子树中的所有节点都大于该节点。合并两棵二叉树可以通过递归地方式实现。按照中序遍历,如果遍历结果是单调递增的,说明是二叉搜索树。一样,我们使用递归,每一层确定根节点和左右子树元素。递归地搜索,直到找到值相等的节点,或者遍历到空节点。

2024-03-12 00:04:58 403 1

原创 代码随想录|Day16|二叉树05|513.找树左下角的值、112.路径总和、113.路径总和II、106.从中序与后序遍历序列构造二叉树、105.从前序与中序遍历序列构造二叉树

从根节点开始构造二叉树,首先定位到后序遍历的最后一个元素,其为此二叉树的根节点。当到达节点3时,若先遍历右子树到达节点5,此时由于5是叶子结点且深度更大,我们会收集节点5,并更新最大深度为3。回到节点3,接着遍历左子树到达节点4,此时虽然4是叶子结点,但是深度并不大于3,因此不会记录节点4。,用于记录遍历到某叶子节点时,当前的最大深度,当我们到达新的叶子节点时,检查这个深度是否大于。的顺序,否则,左右叶子节点否存在的情况下,会优先保存右叶子节点。如下图所示,节点4是需要收集的最终结果。

2024-03-10 00:17:23 345 1

原创 代码随想录|Day15|二叉树04|110.平衡二叉树、257.二叉树的所有路径、404.左叶子之和

什么是平衡二叉树?对于平衡二叉树中的任何一个节点,其左右子树的高度差不超过。前序、中序还是后序?求二叉树的高度需要使用后序遍历,通过求出左右子树的高度后,返回给父节点。举一个例子,根节点的左子树高度是多少?按照后序,首先定位到根节点的左子节点,以节点为根节点的子树的高度是多少?按照后序,首先定位到根节点的左子节点,以节点为根节点的子树的高度是多少?按照后序,以节点为根节点的子树,没有左右子节点,接着访问中节点,也就是节点,高度为。至此,以节点为根节点的子树的左子树高度为。同理,以节点。

2024-03-08 23:03:48 312 1

原创 代码随想录|Day14|二叉树03|104.二叉树的最大深度、111.二叉树的最小深度、222.完全二叉树的节点个数

在完全二叉树中,除了最底层外,其他每层节点数都达到最大值,且最底层的节点集中在左侧。这意味着如果一棵完全二叉树的最左侧路径的深度等于最右侧路径的深度,那么这棵树是满二叉树,其节点数可以直接通过 2^n − 1 计算。本题求解最大深度,但根节点的高度等于二叉树的最大深度,因此两者都可行。节点的高度:该节点到最远叶子节点的最长路径上的边的数量。最小深度:根节点到最近叶子节点的路径边数,没有子节点的节点叫叶子结点。节点的深度:从根节点到该节点的路径上的边的数量。如果求节点的深度,应该从上至下,采用前序遍历。

2024-03-07 23:09:22 331

原创 代码随想录|Day13|二叉树02|102.二叉树的层序遍历、226.翻转二叉树、101. 对称二叉树

思路:为了保持对称性,对于树中的任意两个对称位置的节点,它们要么都为空(表示对称位置都没有子树),要么都非空且值相等(表示对称位置的子树结构和节点值相匹配)。这里给出前序遍历(包括递归和迭代)和层序遍历的代码,后序遍历也可以,只需交换代码顺序即可。二叉树的层序遍历先访问树的上层节点,然后逐层向下,直到达到树的底部。同时对于出队的每个节点,将其左右子节点入栈。此时我们完成了一层的遍历,同时队列中保存了下一层的所有节点。第一层只会存在一个根节点,我们将其入队,并记录队列的长度。思路:反转每个节点的左右子树。

2024-03-06 23:44:12 337 1

原创 代码随想录|Day12|二叉树01|理论基础、递归遍历、迭代遍历

二叉树是每个节点最多有两个子节点的树结构。在二叉树中,每个节点包含三个基本部分:一个数据元素(称为“键值”)、指向左子节点的指针和指向右子节点的指针。如果某个子节点不存在,相应的指针为空。

2024-03-05 22:18:03 1576 1

原创 代码随想录|Day11|栈与队列03|239. 滑动窗口最大值、347. 前 K 个高频元素

堆(Heap)是一种特殊的完全二叉树,它满足每个节点的值都不大于(或不小于)其子节点的值的性质。重复此过程直到新元素小于队尾元素,此时新元素应该入队,形成新的单调队列。时间复杂度内访问到最小元素(在最小堆中)或最大元素(在最大堆中),并且可以在。个最高频率,不依赖排序,而是采用优先队列(堆),时间复杂度可以降为。实现的方法是构造单调队列,队内元素从大到小排列,队列首位即最大值。暴力:遍历整个数组,对于每个窗口,遍历找出最大值,时间复杂度为。暴力:哈希表记录所有元素的频率,然后对频率排序,时间复杂度。

2024-03-04 20:48:17 502 1

原创 代码随想录|Day10|栈与队列02|20. 有效的括号、1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值

例如:4 + 13 / 5,这就是中缀表达式,计算机从左到右去扫描的话,扫到13,还要判断13后面是什么运算符,还要比较一下优先级,然后13还和后面的5做运算,做完运算之后,还要向前回退到 4 的位置,继续做加法,你说麻不麻烦!那么将中缀表达式,转化为后缀表达式之后:["4", "13", "5", "/", "+"] ,就不一样了,计算机可以利用栈来顺序处理,不需要考虑优先级了。如一下动画所示,如果遇到数字,直接入栈,如果遇到运算符,则取出栈顶2个数字进行运算。当遍历到右括号,就从栈顶弹出对应右括号,

2024-03-02 16:08:08 679

原创 代码随想录|Day09|栈与队列01|232.用栈实现队列、225. 用队列实现栈

是一种 先进后出 的数据结构,最先入栈的元素最后出栈。可以想像栈为一支窄试管,存放了一列豆子,我们需要垂直握着试管,要想拿到底部的豆子,必须先拿走试管口的豆子,因此栈的出口处被称为 栈顶,底部为 栈底。是一种 先进先出 的数据结构,最先入队的元素最先出队。同样以试管举例,只不过这次的试管没有底,是连通的玻璃管,我们需要水平拿着试管。,将除了最后一个添加的元素之外的所有元素重新入队,这样可以确保最先添加的元素始终在队列的末尾,此时使用。,最先添加的元素将会是最后一个出队的,也就是说,的队首为模拟的栈顶。

2024-03-01 21:42:34 585

原创 代码随想录|Day07|字符串01|344.反转字符串、541. 反转字符串II、151. 反转字符串中的单词

思路:将字符串按空格拆分为列表,里面包含所有单词,接着使用双指针反转所有单词。熟悉双指针的同学,这题应该可以秒了。在字符串末尾,如果剩余字符不足。个,双指针可以顺利反转前。个,需要反转所有剩余字符。1. 剩余字符数量介于。2. 剩余字符数量不到。

2024-02-28 17:10:25 618 1

原创 代码随想录|Day06|哈希表02|454. 四数相加II、383. 赎金信、15. 三数之和、18. 四数之和

后,本题的思路其实是一样的,只是我们现在需要先确定两个元素,然后使用双指针在后面的元素中寻找符合条件的四元组。思路:我们遍历列表,对于每个元素,我们通过使用双指针在其之后的元素中寻找符合条件的三元组。因此,本题采用双指针对排序数组进行操作,因此剪枝会更加直接。本题需要注意去重,因此使用哈希法的时候,剪枝比较困难。类似,区别不过是本题需要两列表为一组遍历。首先我们两个for循环遍历出列表。中出现,因此判断条件有所区别。中出现的字母并不一定全部在。中寻找补数的出现次数。

2024-02-27 22:34:55 473

原创 代码随想录|Day05|哈希表01|242.有效的字母异位词、349. 两个数组的交集、202. 快乐数 、1. 两数之和

如果存在,那么就找到了一对符合条件的元素,并可以直接返回它们的下标。双指针思路:现将列表排序,接着分别定义一个指针指向列表首位,每次对比指针所指元素,如果相等则放入事先定义的。这样我们就能记录每个字符出现的次数,最后遍历 s 和 t,对比两个字典即可。1. 某平方和重复出现,则说明此数字会无限循环,一定不是快乐数。由于要记录字符出现的次数,给出两种记数方式:字典和列表。列表并没有这种结构,如何构建字符和位置的对应关系呢?中每个字符出现的次数都相同,则互为字母异位词。,构建位置映射,并对应一个。

2024-02-26 20:37:00 825 1

原创 代码随想录|Day04|链表02|24. 两两交换链表中的节点、19. 删除链表的倒数第N个节点、160. 链表相交、142. 环形链表II

与不同的是,这次是每对节点两两交换。因此可以考虑定义三个指针,和分别指向需要交换的节点,则指向此节点对的前一节点。交换后,在前,在后,此时令指向,然后移动至,开启下一节点对的交换。此步骤非常重要,目的是为了连接所有交换后的节点对。

2024-02-25 00:53:11 467

原创 代码随想录|Day03|链表01|203. 移除链表元素、707. 设计链表、206. 反转链表

这由链表的性质决定,其内存并不如数组那样是连续的,而是通过各节点中保存的指针,连接零散的内存,如链子一般。举例来说,一个节点除了包含值。如此一来头节点便和其他节点一样,可采用相同的操作逻辑,而无需特殊处理。因此,若不遍历链表,无法得知链表长度,若想要到达某节点,只能通过从头遍历实现。反转所有节点的指针指向,听起来很简单,但实际操作可能有点烧脑,容易转晕。自行设计链表的基础操作,对理解链表有极大的帮助,同时也考察类 (,其指向下一个节点,最后一个节点的指针指向。注意,反转后,原头节点变为末节点,需要指向。

2024-02-23 16:33:23 629

原创 代码随想录|Day02|数组02|977. 有序数组的平方、209. 移长度最小的字数组、59. 螺旋矩阵II

我们使用双指针来维护一个滑动窗口,左右指针指向第一个元素,右指针先行,直到找到一个满足条件的窗口,此时只需要寻找更短的窗口,通过移动左指针缩小窗口,维护一个 min_len。本题的关键是,起始点 startx、starty、边界 n - offset ,以及填充顺序的理解。由于平方后较大值一定在两端,因此使用双指针从两端向中间遍历,每次取较大值插入新开辟的数组。思路:实际上,当找到一个符合条件的子数组, 不需要再去判断任何更长的子数组。2. 若包含负数,平方后数组的较大值在左端或右端,呈山谷状。

2024-02-22 16:24:33 592

原创 代码随想录|Day01|数组01|704. 二分查找、27. 移除元素、35. 搜索插入位置、34. 在排序数组中查找元素的第一个和最后一个位置

单个for循环暴力遍历,时间复杂度为。由于本题是一个有序数组,并且无重复元素,因此可以考虑使用效率更高的二分法。首先将整个数组设想为一个左闭右闭的区间,然后将区间中点的元素与目标元素对比。在本题非递减数组的情况下,如果则说明我们的在右边,此时只需将左边界更新为。二分法使得每次搜索的规模减半,搜索次数为,时间复杂度为。

2024-02-21 21:02:20 575

空空如也

空空如也

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

TA关注的人

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