算法/LeetCode
文章平均质量分 55
算法,刷题复习
#小学生
这个作者很懒,什么都没留下…
展开
-
八大排序算法
冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。因为排序的过程中,各元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序,因此要在排序过程中设置一个标志flag判断元素是否进行过交换。从而减少不必要的比较。稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面;原创 2022-11-12 18:17:22 · 1122 阅读 · 0 评论 -
时间复杂度和空间复杂度详解及排序算法复杂度
1、事前估算法通过分析某个算法的时间复杂度来判断哪个算法更优2、事后统计法这种方法可行,但是有两个问题:一是要想对设计的算法的运行性能进行评测,需要实际运行该程序;二是所得时间的统计量依赖于计算机的硬件、软件等环境因素,这种方式,要在同一台计算机的相同状态下运行,才能比较哪个算法速度更快。原创 2022-11-10 11:55:12 · 330 阅读 · 0 评论 -
LeetCode739:每日温度
给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。原创 2022-11-03 19:33:52 · 853 阅读 · 0 评论 -
LeetCode647:回文子串
给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。回文字符串 是正着读和倒过来读一样的字符串。子字符串 是字符串中的由连续字符组成的一个序列。具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。原创 2022-11-03 18:19:26 · 172 阅读 · 0 评论 -
LeetCode621:任务调度器
给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。在任何一个单位时间,CPU 可以完成一个任务,或者处于待命状态。然而,两个 相同种类 的任务之间必须有长度为整数 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。你需要计算完成所有任务所需要的 最短时间。原创 2022-11-03 16:10:05 · 297 阅读 · 0 评论 -
LeetCoed617:合并二叉树
给你两棵二叉树: root1 和 root2。想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。返回合并后的二叉树。注意: 合并过程必须从两个树的根节点开始。原创 2022-11-03 14:19:47 · 235 阅读 · 0 评论 -
LeetCode581:最短无序连续子数组
给你一个整数数组 nums ,你需要找出一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。请你找出符合题意的 最短 子数组,并输出它的长度。原创 2022-11-03 10:52:10 · 156 阅读 · 0 评论 -
LeetCode560:和为K的子数组
给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的连续子数组的个数。原创 2022-11-02 21:07:03 · 93 阅读 · 0 评论 -
LeetCode543:二叉树的直径
给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。原创 2022-11-02 20:00:30 · 71 阅读 · 0 评论 -
LeetCode538:把二叉搜索树转换为累加树
给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。原创 2022-11-02 15:03:15 · 129 阅读 · 0 评论 -
LeetCode494:目标和
例如,nums = [2, 1] ,可以在 2 之前添加 ‘+’ ,在 1 之前添加 ‘-’ ,串联起来得到表达式 “+2-1”。3、dp[j]代表的意义:填满容量为j的背包,有dp[j]种方法。当前填满容量为j的包的方法数 = 之前填满容量为j的方法数 + 之前填满容量为j - num的包的方法数。也就是当前数num的加入,可以把之前和为j - num的方法数加入进来。4、状态转移:dp[j] = dp[j] + dp[j - num],1、假设所有符号为+的元素和为x,符号为-的元素和的。原创 2022-10-31 20:51:09 · 270 阅读 · 0 评论 -
LeetCode461:汉明距离
时间复杂度:O(1)。不同语言的实现方法不一,我们可以近似认为其时间复杂度为 O(1)。大多数编程语言都内置了计算二进制表达中 1 的数量的函数。我们应该直接使用内置函数。两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。本身不改变 x 和 y,每次取不同的偏移位进行比较,不同则加一。给你两个整数 x 和 y,计算并返回它们之间的汉明距离。时间复杂度:O©,C 固定为 32。循环固定取满 32。空间复杂度:O(1)空间复杂度:O(1)原创 2022-10-31 16:20:50 · 92 阅读 · 0 评论 -
LeetCode448:找到所有数组中消失的数字
可以把数组中的元素与索引建立一一对应的关系。因为索引是确定的0到n-1,nums[i] 在区间 [1, n] 内;既然两者是一一对应的关系,那么我们对数组中的每个元素对应的索引做个标记;给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。2、遍历下索引,看看哪些索引位置上的数不是负数的。1、遍历每个元素,对索引进行标记。原创 2022-10-31 14:58:39 · 123 阅读 · 0 评论 -
LeetCode438:找到字符串中所有字母异位词
right当前遍历到的字符加入s_cnt后不满足p_cnt的字符数量要求,将滑动窗口左侧字符不断弹出,也就是left不断右移,直到符合要求为止。时间复杂度:O(n),for循环有O(n),数组的长度是常数,所以数组的比较也是常数级别的,那最终的时间复杂度就是O(n)给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。用双指针来表示滑动窗口的两侧边界,当滑动窗口的长度等于p的长度时,表示找到一个异位词。当滑动窗口的长度等于p的长度时,这时的s子字符串就是p的异位词。原创 2022-10-31 14:05:29 · 304 阅读 · 0 评论 -
LeetCode437:路径总和III
给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。HashMap的key是前缀和, value是该前缀和的节点数量,记录数量是因为有出现复数路径的可能。路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。节点8的前缀和:1 + 2 + 4 + 8 = 15。节点9的前缀和:1 + 2 + 5 + 9 = 17。节点3的前缀和为: 1 + 2 + 3 = 6。原创 2022-10-30 21:20:10 · 195 阅读 · 0 评论 -
LeetCode416:分割等和子集
不选择 nums[i],如果在 [0, i - 1] 这个子区间内已经有一部分元素,使得它们的和为 j ,那么 dp[i][j] = true;选择 nums[i],如果在 [0, i - 1] 这个子区间内就得找到一部分元素,使得它们的和为 j - nums[i]。原创 2022-10-30 20:15:43 · 229 阅读 · 0 评论 -
LeetCode406:根据身高重建队列
假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序)。每个 people[i] = [hi, ki] 表示第 i 个人的身高为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。请你重新构造并返回输入数组 people 所表示的队列。返回的队列应该格式化为数组 queue ,其中 queue[j] = [hj, kj] 是队列中第 j 个人的属性(queue[0] 是排在队列前面的人)。原创 2022-10-30 16:15:34 · 58 阅读 · 0 评论 -
LeetCode399:除法求值
题目给出的 equations 和 values 可以表示成一个图,equations 中出现的变量就是图的顶点,「分子」于「分母」的比值可以表示成一个有向关系(因为「分子」和「分母」是有序的,不可以对换),并且这个图是一个带权图,values 就是对应的有向边的权值。如下图所示,除了根结点以外,所有的结点的父亲结点都指向了根结点。具体来说,可以把 不同的变量的比值转换成为相同的变量的比值,这样在做除法的时候就可以消去相同的变量,然后再计算转换成相同变量以后的系数的比值,就是题目要求的结果;原创 2022-10-30 14:48:43 · 59 阅读 · 0 评论 -
LeetCode394:字符串解码
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。记录此 [ 前的倍数 multi 至栈,用于发现对应 ] 后,获取 multi × […cur_multi是当前 [ 到 ] 内字符串的重复倍数,例如 “3[a2[c]]” 中的 2。输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。last_res是上个 [ 到当前 [ 的字符串,例如 “3[a2[c]]” 中的 a;给定一个经过编码的字符串,返回它解码后的字符串。原创 2022-10-29 19:05:08 · 73 阅读 · 0 评论 -
LeetCode347:前 K 个高频元素
堆是一颗完全二叉树,树中每个结点的值都不小于(或不大于)其左右孩子的值。如果父亲结点是大于等于左右孩子就是大顶堆,小于等于左右孩子就是小顶堆。可以用priority_queue(优先级队列)实现,底层实现都是一样的,从小到大排就是小顶堆,从大到小排就是大顶堆。给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。我们要用小顶堆,因为要统计最大前k个元素,只有小顶堆每次将最小的元素弹出,最后小顶堆里积累的才是前k个最大元素。要统计元素出现频率 —>使用map。原创 2022-10-29 17:25:20 · 258 阅读 · 0 评论 -
LeetCode338:比特位计数
给你一个整数 n ,对于 0原创 2022-10-29 15:03:35 · 301 阅读 · 0 评论 -
LeetCode337:打家劫舍III
小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root。除了 root 之外,每栋房子有且。把每次的结果存储起来,下次再计算的话,从缓存中取,避免重复计算;二叉树不适合数组存储,所以使用哈希表进行存储结果。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。从下往上遍历 —> 从子节点往父节点去遍历,一层层向上汇报,也就是后序遍历:左右根。给定二叉树的 root。返回在不触动警报的情况下, 小偷能够盗取的最高金额。在同一天晚上被打劫 ,房屋将自动报警。原创 2022-10-29 11:41:54 · 643 阅读 · 0 评论 -
LeetCode322:零钱兑换
计算并返回可以凑成总金额所需的 最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。时间复杂度:O(N×amount),这里 N 是可选硬币的种类数,amount是题目输入的面值;给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。单枚硬币的面值首先要小于等于 当前需要的面值;剩余的面值也要能够凑出来,否则返回-1。空间复杂度:O(amount),状态数组的大小为 amount。你可以认为每种硬币的数量是无限的。原创 2022-10-29 10:06:22 · 161 阅读 · 0 评论 -
LeetCode312:戳气球
base case 就是 dp[i][j] = 0,其中 0原创 2022-10-28 18:55:39 · 297 阅读 · 0 评论 -
LeetCode309:最佳买卖股票时机含冷冻期
给定一个整数数组prices,其中第 prices[i] 表示第 i 天的股票价格 。设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。卖出股票后的第 2 天为冷冻期。即:方法:动态规划1、状态定义:dp[i][j] 表示 [0, i] 区间内,在下标为 i 这一天状态为 j 时,我们手上拥有的金钱数。这里的 j 可以原创 2022-10-28 11:31:38 · 374 阅读 · 0 评论 -
LeetCode301:删除无效的括号
不考虑 score带来的剪枝效果,最坏情况下,每个位置都有两种选择,搜索所有方案的复杂度为 O(2^ n );同时搜索过程中会产生的新字符串(最终递归树中叶子节点的字符串长度最大为 n,使用 StringBuilder 也是同理),复杂度为O(n)。整体复杂度为 O(n * 2^n)使用 Set 进行方案去重,我们可以通过预处理,得到最后的「应该删除的左括号数量」和「应该删掉的右括号数量」,来直接得到最终的 len;可以预处理搜索过程的最大得分: max = min(左括号的数量, 右括号的数量)原创 2022-10-27 20:54:33 · 449 阅读 · 0 评论 -
LeetCode300:最长递增子序列
这个定义中 nums[i] 必须被选取,且必须是这个子序列的最后一个元素;原创 2022-10-27 17:00:59 · 278 阅读 · 0 评论 -
LeetCode297:二叉树的序列化和反序列化
序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。提示: 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。DFS遍历是从根节点开始,一直往左子节点走,当到达叶子节点的时候会返回到父节点,然后从从父节点的右子节点继续遍历……只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。原创 2022-10-27 11:53:05 · 163 阅读 · 0 评论 -
LeetCode287:寻找重复数
时间复杂度:O(NlogN),二分法的时间复杂度为O(logN),在二分法的内部,执行了一次 for 循环,时间复杂度为 O(N),故时间复杂度为 O(NlogN)。我们从下标为 0 出发,根据 f(n) 计算出一个值,以这个值为新的下标,再用这个函数计算,以此类推,直到下标超界。同样的,我们从下标为 0 出发,根据 f(n) 计算出一个值,以这个值为新的下标,再用这个函数计算,以此类推产生一个类似链表一样的序列。假设 nums 只有 一个重复的整数 ,返回 这个重复的数。空间复杂度:O(1)。原创 2022-10-27 11:05:27 · 651 阅读 · 0 评论 -
LeetCode283:移动零
这里我们可以用0当做这个中间点,把不等于0(注意题目没说不能有负数)的放到中间点的左边,等于0的放到其右边。即遍历的时候每遇到一个非0元素就将其往数组左边挪,第一次遍历完后,‘j’ 指针的下标就指向了最后一个非0元素下标。这里参考了快速排序的思想,快速排序首先要确定一个待分割的元素做中间点x,然后把所有小于等于x的元素放到x的左边,大于x的元素放到其右边。第二次遍历的时候,起始位置就从 ‘j’ 开始到结束,将剩下的这段区域内的元素全部置为0。空间复杂度: O(1)空间复杂度: O(1)原创 2022-10-26 20:52:41 · 148 阅读 · 0 评论 -
LeetCode279:完全平方数
完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。给你一个整数 n ,返回 和为 n 的完全平方数的最少数量。原创 2022-10-26 18:53:56 · 146 阅读 · 0 评论 -
LeetCode253:会议室II
给你一个会议时间安排的数组 intervals ,每个会议时间都会包括开始和结束的时间 intervals[i] = [starti, endi] ,返回 所需会议室的最小数量。对于当前的会议,如果开始时间小于优先队列元素的会议结束时间,就需要新开一个房间,因此将它重新入队。输入:intervals = [[0,30],[5,10],[15,20]]将所有会议按照开始时间排序,优先队列存储会议的结束时间由小到大排序。原创 2022-10-26 14:32:24 · 189 阅读 · 0 评论 -
LeetCode240:搜索二维矩阵 II
数组从左到右和从上到下都是升序的,如果从右上角出发开始遍历,会发现每次都是向左数字会变小,向下数字会变大;编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。看到有序,第一反应就是二分查找。一行一行的进行二分查找即可。遍历整个矩阵matrix,判断target是否出现即可。看不懂上面的写法的话,看下面这种。时间复杂度:O(m∗logn)时间复杂度:O(m + n)空间复杂度:O(1)空间复杂度:O(1)原创 2022-10-26 11:13:21 · 231 阅读 · 0 评论 -
LeetCode238:除自身以外数组的乘积
空间复杂度:O(N),其中 N 指的是数组 nums 的大小。使用了 L 和 R 数组去构造答案,L 和 R 数组的长度为数组 nums 的大小。给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。对于给定索引 i,L[i] 代表的是 i 左侧所有数字的乘积,R[i] 代表的是 i 右侧所有数字的乘积。当 R 和 L 数组填充完成,我们只需要在输入数组上迭代,且索引 i 处的值为:L[i] * R[i]。原创 2022-10-25 15:15:49 · 89 阅读 · 0 评论 -
LeetCode236:二叉树的最近祖先
设节点 root 为节点 p,q 的某公共祖先,若其左子节点 root.left和右子节点 root.right 都不是 p,q 的公共祖先,则称 root 是 “最近的公共祖先”原创 2022-10-25 10:53:26 · 60 阅读 · 0 评论 -
LeetCode236:回文链表
算法的正确性在于递归处理节点的顺序是相反的(回顾上面打印的算法),而我们在函数外又记录了一个变量,因此从本质上,我们同时在正向和逆向迭代匹配。计算机在递归的过程中将使用堆栈的空间,这就是为什么递归并不是 O(1) 的空间复杂度。给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。下面的动画展示了算法的工作原理。指针是先到尾节点,由于递归的特性再从后往前进行比较。时间复杂度:O(n),其中 n 指的是链表的大小。空间复杂度:O(n),其中 n 指的是链表的大小。下面是官方的代码,消耗的内存少。原创 2022-10-24 16:11:21 · 232 阅读 · 0 评论 -
LeetCode226:翻转二叉树
其实就是交换一下左右节点,然后再递归的交换左节点,右节点;空间复杂度:最坏的情况下,需要存放 O(h) 个函数调用(h是树的高度),所以是 O(h)给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。时间复杂度:每个元素都必须访问一次,所以是 O(n)原创 2022-10-24 14:37:52 · 192 阅读 · 0 评论 -
LeetCode221:最大正方形
回到图解中,任何一个正方形,我们都「依赖」当前格 左、上、左上三个方格的情况;但第一行的上层已经没有格子,第一列左边已经没有格子,需要做特殊 if 判断来处理为了代码简洁,我们 假设补充 了多一行全 ‘0’、多一列全 ‘0’;此时 dp 数组的大小也明确为 new dp[height + 1][width + 1] 初始值就是将第一列 dp[row][0] 、第一行 dp[0][col] 都赋为 0,相当于计算了第一行、第一列的 dp 值。原创 2022-10-24 11:44:00 · 308 阅读 · 0 评论 -
LeetCode215:数组中的第k个最大元素
数组排序后的第 k 个最大的元素:换句话说就是从右往左数第k个元素,即数组长度len - k;在 for 循环里面判断小顶堆里面的 size() 是否大于 k 个数,是的话就 poll() 出去;堆顶即第 k 大的数。这句话的意思是,如果数组当中有值相同的元素,他们不能够合并成一个元素;请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。原创 2022-10-23 16:51:04 · 120 阅读 · 0 评论 -
LeetCode208:实现 Trie (前缀树)
boolean startsWith(String prefix) 如果之前已经插入的字符串 word 的前缀之一为 prefix ,返回 true;boolean search(String word) 如果字符串 word 在前缀树中,返回 true(即,在检索之前已经插入);使用 count[] 数组记录某个格子被「被标记为结尾的次数」(当 idx 编号的格子被标记了 n 次,则有 cnt[idx]=n)。此外,若前缀末尾对应节点的 isEnd 为真,则说明字典树中存在该字符串。原创 2022-10-23 14:40:56 · 140 阅读 · 0 评论