
LeetCode热题 100
LeetCode热题 100
程序员萌芽
夜半荧屏映月华,
指尖飞舞写天涯。
代码千行凝智慧,
bug除尽见朝霞。
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
【LeetCode热题100】【多维动态规划】编辑距离
要么替换,需要将word1[0:i-2]转换成word2[0:j-2],即dp[i][j]=dp[i-1][j-1]+1。要么插入,需要将word1[0:i-1]转换成word2[0:j-2],即dp[i][j]=dp[i][j-1]+1。要么删除,需要将word1[0:i-2]转换成word2[0:j-1],即dp[i][j]=dp[i-1][j]+1。定义dp[i][j]是将word1[0:i-1]转换成word2[0:j-1]所使用的最少操作数。你可以插入、删除、替换字符。原创 2024-04-23 20:26:01 · 418 阅读 · 0 评论 -
【LeetCode热题100】【多维动态规划】最长回文子串
用一个二维布尔数组dp,dp[i][j]表示字符串s[i,j]是不是回文字符串,取决于s[i]是否等于s[j]并且dp[i+1][j-1]为真或者i和j之间没有或者只有一个字符。如果暴力的话,两层循环找出所有子串,一层循环判断回文,这样重复判断了回文,存在这样的一个事实:如果s[i,j]是回文字符串,那么s[i+1,j-1]也是回文字符串。二维动态规划数组,由于dp[i][j]需要dp[i+1][j-1],所以需要从左下角开始往右上角遍历。原创 2024-04-23 16:45:23 · 506 阅读 · 0 评论 -
【LeetCode热题100】【多维动态规划】最小路径和
经典动态规划问题,到达当前格子的路径和要么是加上从上面格子来的,要么是加上左边格子来的,取这两个方向来的较小者就行了。,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。对于最左边的和最上边的没有两个方向,可以直接累加一个方向的。每次只能向下或者向右移动一步。给定一个包含非负整数的。原创 2024-04-23 16:03:25 · 351 阅读 · 0 评论 -
【LeetCode热题100】【多维动态规划】不同路径
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。问总共有多少条不同的路径?经典动态规划问题,当前格子的路径数等于上方格子的路径数加上左边格子的路径数,最左边一束和最上边一横路径数都是1。网格的左上角 (起始点在下图中标记为 “Start” )。原创 2024-04-23 15:52:21 · 421 阅读 · 0 评论 -
【LeetCode热题100】【链表】合并 K 个升序链表
合并k个有序链表同样的思路,先循环找出k个链表里面最小的节点,把这个节点当成头节点,同时更新节点原来的链表的头节点为后一个节点,递归合并新的k个链表。合并两个有序链表是找出较小的节点放在前面,更新节点原来的链表的头节点为后一个节点,递归合并新的两个有序链表。要合并k个有序链表,其实和合并两个有序链表是一样的。原创 2024-04-22 16:54:09 · 463 阅读 · 0 评论 -
【LeetCode热题100】【链表】排序链表
拆成两个部分,要保持logn的递归树深度,每次拆分需要拆成两半差不多大小的,也就是寻找链表的中间节点,然后以中间节点为界限分成两个链表,即寻找链表的中间节点:使用快慢指针,当快指针到达链表末尾,慢指针即到达链表中间。然后是考察合并两个有序链表:如果其中一个链表为空,则返回另一个链表,比较两个链表首节点的大小,让小的节点成为新链表的头节点,递归合并后面的。最后是归并排序链表,先找出链表的中间位置拆分成两个链表,递归归并排序两个链表后合并。但是从面试的角度,我们应该在链表原地排序,这里使用最简单的归并排序。原创 2024-04-22 11:14:15 · 714 阅读 · 0 评论 -
【LeetCode热题100】【动态规划】最长递增子序列
让dp[i]是以nums[i]为结尾的子序列的最长递增长度,遍历nums[i]之前的元素,如果有比nums[i]小的,说明递增子序列可以延申。原创 2024-04-19 16:32:12 · 508 阅读 · 0 评论 -
【LeetCode热题100】【链表】随机链表的复制
非常妙的思路,先用一个哈希表将旧链表的节点和新链表的节点一一对应起来,然后将新链表的节点串起来,对于random可以根据哈希表里面的对应找到新链表里面对应的节点,妙哉。,该指针可以指向链表中的任何节点或空节点,请你深拷贝这个链表。的链表,每个节点包含一个额外增加的随机指针。原创 2024-04-21 22:08:41 · 405 阅读 · 0 评论 -
【LeetCode热题100】【子串】最小覆盖子串
先用一个哈希表记录目标字符串target的字符种类及其数量,然后用一个滑动窗口从字符串source上滑过去,i负责起点缩减,j负责终点延申,碰到一个字符,更新它在哈希表里面的数量减一,表示已经找到一个,当数量减到0,表示这个字符已经收集完毕,需要收集的种类数量减一。如果s[i]在哈希表里面的数量小于0,说明s[i]已经多了,i可以往前缩减滑动字符串的长度。当需要收集的字符串的种类已经为0,说明已经找到了,比较和先前找到的长度看是否需要更新。所有字符的子串,则返回空字符串。所有字符的最小子串。原创 2024-04-21 15:32:22 · 529 阅读 · 0 评论 -
【LeetCode热题100】【图论】实现 Trie (前缀树)
这样存储字符串abc和abcd只会多一个d指向的节点,也就是相同的前缀会在相同的节点,每一个字母会有26种后缀,因此有26个指针指向后缀节点,如果某节点指针为空,说明没有该字母后缀。为了判断是否是前缀和存在单词,可以写一个查找前缀的函数,如果前缀存在返回节点指针,代码基本和插入相同,不同的地方在于当不存在当前字母时说明没有该前缀,直接返回空。插入字符串的时候,从头到尾安排单词的每个字母,如果不存在当前字母,为它创建一个新的节点。这应该和图论没啥关系,应该属于哈希和树,题目没讲前缀树到达是啥。原创 2024-04-20 22:13:23 · 690 阅读 · 0 评论 -
【LeetCode热题100】【图论】课程表
入度为0的说明没有先修课程,取出来修,并将相连的节点的入度减一,说明先修课程已经修了一个了,再判断有没有新的课程可以修的入队。先修课程,判断课程能不能修完,这是一个判断拓扑有序的问题,看看会不会成环。先建立有向图,记录每个顶点的入度,把入度为0的入队列。最后判断修了的课程和要修的课程数目是否相等。原创 2024-04-19 23:05:25 · 435 阅读 · 0 评论 -
【LeetCode热题100】【图论】腐烂的橘子
腐烂的橘子会污染周围的橘子,要求多少轮扩散才能把全部橘子污染,这就相当于滴墨水入清水,会扩散,其实就是广度遍历,看看遍历多少层可以遍历完可以遍历的。先遍历一次橘子,记录下腐烂橘子的位置和新鲜橘子的数目,然后广度遍历腐烂橘子并向外扩散污染新鲜橘子。注意向外扩散时需要每次取位置,因为移动会改变位置,位置需要重置。原创 2024-04-19 22:29:54 · 392 阅读 · 0 评论 -
【LeetCode热题100】【图论】岛屿数量
对于这道题来说,从是1的地方深度遍历,改写可以到达的地方,这样就是一个岛屿,如果还有1,说明还有岛屿。首先需要判断图的边界,然后再上下左右继续深度遍历,并把遍历到的标记为已访问,可以原地修改图做标记。考察图的遍历,从岛上上下左右能到达的地方都是这个岛。原创 2024-04-19 21:36:04 · 694 阅读 · 0 评论 -
【LeetCode热题100】【动态规划】最长有效括号
如果是...))这样的,也就是s[i-1]=),也就是套壳状态,那么s[i]必定需要对应一个s[j]=(来闭环,那么j是多少呢,j和i之间应该隔了dp[i-1]个,那么j应该等于i-dp[i-1]-1,dp[i]就应该是dp[i-1]+2再加上dp[j-1],那么状态转移方程应该为。还需要加上数组边界条件的判断。原创 2024-04-19 20:06:09 · 294 阅读 · 0 评论 -
【LeetCode热题100】【动态规划】分割等和子集
判断数组能否被分成两个和相等的子数组,先求数组的和sum,即变成能不能找到一个组合的和是sum/2,每个数最多只能被选择一次,即0-1背包问题。本问题:dp[i]为是否存在和为i的子集,如果选择当前元素,变成是否存在和为i-num的子集。0-1背包状态转移方程:如果选择,那么空间减少,价值增加,dp[i]为空间为i的最大价值。特别注意如果sum是奇数,那么sum/2不是整数肯定不存在。原创 2024-04-17 23:05:51 · 444 阅读 · 0 评论 -
【LeetCode热题100】【动态规划】乘积最大子数组
对于和来讲,定义dp[i]是以nums[i]为结尾的最大子数组的和,那么dp[i]要么就是nums[i]加上之前的dp[i-1],即前一个子数组加上当前元素,要么是nums[i]自己新开一个子数组,所以状态转移方程。但是乘积与和不一样的地方在于负数的情况,负数加负数的和是越来越小的,但是乘积会因为碰到一个负数变成最大或者变成最小,因此需要用两个数组记录状态,dpMin记录最小,dpMax记录最大。要找乘积最大的连续子数组,我们之前做过找和最大的连续子数组。原创 2024-04-19 17:01:49 · 278 阅读 · 0 评论 -
【LeetCode热题100】【动态规划】单词拆分
定义dp[i]是目标字符串中以i为结尾的子串能不能由某个字符串word组成,如果可以,问题变成dp[i-word.size()]即完全背包问题,同之前的完全平方数、零钱兑换,相当于给定几个数,可以反复用,看能不能组成某个数。看能不能用字符串列表里面的字符串组成这个字符串,可以反复使用。此处组合需要考虑顺序,target遍历外层循环。原创 2024-04-19 16:02:31 · 358 阅读 · 0 评论 -
【LeetCode热题100】【动态规划】完全平方数
所以题目变成要从1,2,3,……,n的平方根中找出平方和的和是n的组合,并且数量最少。完全平方数是可以表示成某个整数的平方的数,要找和为n的完全平方数的最少数目。满足要求的完全平方数最小是1,最大不会超过n的平方根。定义dp[i]为和为i的完全平方数的最少数目。原创 2024-04-18 00:23:07 · 371 阅读 · 0 评论 -
【LeetCode热题100】【动态规划】零钱兑换
要拿硬币凑钱,硬币无限多,就是完全背包问题,定义dp[i]是要凑的钱i的硬币数,对于当前硬币来说,如果选择了这个硬币,要么要凑的硬币数就变成dp[i-coin]原创 2024-04-18 00:10:28 · 357 阅读 · 0 评论 -
【LeetCode热题100】【动态规划】打家劫舍
如果有多间,对于第i间来说,让dp[i]是打劫的最大金额,如果要打劫第i间,那么第i-1间就不能打劫,dp[i]=nums[i-1]+dp[i-2],如果不打劫第i间,那么dp[i]=dp[i-1],取这两个的最大值。如果没有房子,那就是0,如果有一间房子,那么就是这间房子,如果有两间,那么就挑一间打劫。注意nums下标从0开始。原创 2024-04-17 19:25:55 · 318 阅读 · 0 评论 -
【LeetCode热题100】【堆】数据流的中位数
不停插入元素要求找到每个状态的中位数,用两个堆,把中位数左边的数记为left,右边的数记为right,一个大顶堆记录小于等于中位数的left,一个小顶堆记录大于中位数的right,数组长度为奇数时大顶堆比小顶堆多一个中位数,数组长度为偶数时,中位数就是两个堆顶的平均值。插入元素时,如果两个堆长度一样,先入小顶堆,这样小顶堆堆顶就是right里面最小的,弹出来放到left里面,此时left比right多一个数,并且left堆顶就是中位数,因为它比right都小,比left都大。注意优先队列默认是大顶堆。原创 2024-04-17 17:09:00 · 415 阅读 · 0 评论 -
【LeetCode热题100】【堆】前 K 个高频元素
要找出前K个出现频率最多的元素,可以先用哈希表存储每个元素出现的次数,然后建立一个容量为K的小顶堆,遍历哈希表找到更高频的元素入堆进行堆调整,最后堆里的元素就是前K个出现次数最多的元素。手写一个堆,就在答案容器基础上建堆,注意比较需要用哈希表比较。原创 2024-04-17 16:08:51 · 328 阅读 · 0 评论 -
【LeetCode热题100】【二分查找】寻找两个正序数组的中位数
这里需要注意j的范围,因为b[j-1]和b[j]可以不存在,比如a=123,b=456,如果要找3,那么i=3,j=0,此时b[i-1]是不存在的,a[i]也是不存在的,因此0<=j<=m,即0<=k-i<=m,即i<=k,i>=k-m。那么如果i+j=k,那么说明a[i]和b[j]前面有k个数,如果a[i-1]<=b[j]并且b[j-1]<=a[i],这就说明这k个数就是合并后有序的前k个数,那么第k大的数就是a[i-1]和b[j-1]之间的较大者。原创 2024-04-17 14:42:39 · 493 阅读 · 0 评论 -
【LeetCode热题100】【二分查找】寻找旋转排序数组中的最小值
因为要找最小值,如果二分后左边有序,那么左边边的那个就是左边最小的,此时更小的只会出现在右边,继续二分右边;如果二分后左边无序,那么说明最小的一定出现在左边,继续二分左边的。要在一个561234这样的数组里面找最小值,注意每次二分可以拆出要么两个升序数组(456、123),要么拆出一个升序数组和一个具有同样性质的数组(561、234)原创 2024-04-16 23:18:28 · 226 阅读 · 0 评论 -
【LeetCode热题100】【二分查找】搜索旋转排序数组
因为题目说了元素不超过10000,那么就给第二段升序的部分加上10000,这样就是升序数组了,如果目标元素小于nums[0]说明它在第二段里面,也给它加上10000,不要误会循环加是O(n)的复杂度,只需要在比较的时候相加即可。同样是要在数组中查找元素,不同的是这次的数组是这样//的,升序数组,但是往前移动了一下,也就是两段升序,456123这样。看了一位天才的思路,把分段升序数组变成单纯的升序数组然后直接二分。原创 2024-04-16 22:41:42 · 417 阅读 · 0 评论 -
【LeetCode热题100】【二分查找】在排序数组中查找元素的第一个和最后一个位置
先用二分找到元素的位置,然后往前找第一次出现的位置,往后找最后一次出现的位置。原创 2024-04-16 16:53:27 · 129 阅读 · 0 评论 -
【LeetCode热题100】【二分查找】搜索二维矩阵
如果用二分查找,时间复杂度是log(mn),但是可以实现时间复杂度为O(m+n)的,从右上角开始查找,如果当前元素比目标小,说明应该在下面范围,矩阵压扁,如果当前元素比目标大,说明在左边范围,矩阵压扁,这样最多只需要遍历m+n个元素可以确定元素是否存在。在一个有序二维数组里面查找元素,同。原创 2024-04-16 15:46:36 · 422 阅读 · 0 评论 -
【LeetCode热题100】【二分查找】搜索插入位置
为什么return left,可以知道过程中left的左侧小于目标,right的右侧大于目标,当循环跳出时有left等于right+1,也就是right在left的左侧,即left比目标大,而right比目标小,所以目标的插入位置应该是left。要在一个有序数组里面查找一个元素的位置,就是要找第一个大于等于目标元素的位置,每次和中间位置元素进行比较,然后确定下一次的查找范围是在左半部分还是右半部分。原创 2024-04-16 15:36:56 · 295 阅读 · 0 评论 -
【LeetCode热题100】【贪心算法】划分字母区间
可以先用一个数组记录每个字母的最后出现的位置,然后再次遍历字符串,如果当前字母的位置就是该字母最后出现的位置,那么此处应该分离。如果一个字母的当前位置是它在这个字符串里面最后一次出现的位置,那么这里就应该划分出来成为子串。要将一个字符串划分为多个子串,要求每个字母只能出现在一个子串里面。原创 2024-04-16 15:17:21 · 529 阅读 · 0 评论 -
【LeetCode热题100】【贪心算法】跳跃游戏 II
逻辑就是如果我到达了可以到达的最远位置,说明我跳了一次,可以理解为上一次跳跃完成,但是由于最后一次跳跃也是跳最远距离可能超过了最后一个位置,无法计数,所以一开始00的时候就计数了一次,并且最后一次不计数。不断更新当前可以跳跃到达的最远距离farthest,记录上次跳跃可以到达的位置foothold,当到这个位置的时候,跳跃计数,更新foothold为farthest。数组的元素表示可以跳的最大长度,保证可以跳到最后,求跳的最少的次数。原创 2024-04-15 23:45:05 · 342 阅读 · 0 评论 -
【LeetCode热题100】【贪心算法】跳跃游戏
不断更新可以跳到的最远距离,如果当前的位置大于可跳最远距离,说明不行。数组的元素表示可以跳的最大长度,要判断能不能跳到最后。原创 2024-04-15 22:58:32 · 411 阅读 · 0 评论 -
【LeetCode热题100】【矩阵】搜索二维矩阵 II
从右上角开始搜索,如果当前元素比目标小,那么说明目标只能存在下面矩阵,搜索范围往下压扁,如果当前元素比目标大,说明目标只能存在左边的矩阵里,搜索范围往左压窄。这样最多需要遍历n+m个元素就可以搜索完毕。原创 2024-04-15 22:06:06 · 666 阅读 · 0 评论 -
【LeetCode热题100】【矩阵】旋转图像
要将一个矩阵顺时针旋转90°,数学公式是new[j][n-i-1]=old[i][j],要原地翻转的话,可以先水平翻转,即变成m[n-i-1][j],再主对角线翻转(即转置),变成m[j][n-i-1]原创 2024-04-15 21:31:38 · 343 阅读 · 0 评论 -
【LeetCode热题100】【矩阵】螺旋矩阵
先走外面的圈再走里面的圈,可以用递归来解决,对于要走的一个圈,由四个角决定,其实是三个数,(0,0),(0,n),(m,0),(m,n),每次先从左上角走到右上角,再走到右下角,再走到左下角,再走回来。对于后面两个的往回走要在m和n不等于起点的情况下,否则会重复最后。不用递归也可以,改成迭代。原创 2024-04-15 21:18:30 · 376 阅读 · 0 评论 -
【LeetCode热题100】【矩阵】矩阵置零
用两个数组标记要变成0的行和列索引。原创 2024-04-15 20:30:38 · 382 阅读 · 0 评论 -
【LeetCode热题100】【数组】缺失的第一个正数
要找出这个数组里面没有出现的最小的正数,最小的正数是1,n个元素的数组能够让答案最大为n+1,也就是位置0对应1,位置1对应2……如果我们按照这样的对应关系重新整理一下数组,从0到n-1遍历,num[i]和i+1不相等的就是缺失的最小的正数。如何整理数组呢,找到范围在1到n之间的num[i],它正确的位置应该在num[i]-1,交换这两个的值。原创 2024-04-15 19:09:52 · 355 阅读 · 0 评论 -
【LeetCode热题100】【数组】除自身以外数组的乘积
只能用一个输出数组的话,可以先用这个数组记录前缀累积,然后再用一个变量记录后缀累积,用前缀累积乘以后缀累积就是答案。要找除开本身以外其他元素的乘积,如果可以用除法的话,直接累积所有元素然后除以每个元素。不能用除法,可以用两个数组计算元素的前缀乘积和后缀乘积,然后相乘即可。原创 2024-04-15 17:13:32 · 277 阅读 · 0 评论 -
【LeetCode热题100】【回溯】N皇后
我们一层一层来摆,这样后面的层因为没有摆,所以判断冲突的时候不需要考虑后面的层,并且这层摆了一个就摆下一层,所以水平方向不需要判断冲突。因此需要写一个判断冲突的函数,判断当前位置往上,往左上,往右上有没有冲突。经典问题,N个皇后,N×N棋盘,直线上不能有多个皇后,找摆法。深度遍历回溯查找可行方案。原创 2024-04-15 15:59:10 · 713 阅读 · 0 评论 -
【LeetCode热题100】【回溯】分割回文串
要找出所有分割这个字符串的方案使得每个子串都是回文串,写一个判断回文串的函数,深度遍历回溯去找出所有分割方案,判断分割的子串是否是回文串。原创 2024-04-15 15:25:33 · 264 阅读 · 0 评论 -
【LeetCode热题100】【回溯】单词搜索
要在一个二维数组里面找到一条单词路径,可以先遍历二维数组找到单词入口,然后往上下左右深度遍历,访问过的元素直接修改成字符串结束符,访问完改回去。原创 2024-04-15 14:13:13 · 423 阅读 · 0 评论