leetcode经典题目
zcz5566719
这个作者很懒,什么都没留下…
展开
-
【经典题目】统计1~n中1的出现次数
文章目录其实有点类似与计数DP的思路。但是我觉着这个问题的思路还是非常的巧妙的值得学习。首先将一个数字分为了两个部分,比如123456,高位high = 1234, 低位low = 6,当前位cur = 5。额外有当前的位的数量级digit;因为我们分析的是1的出现次数。那么有三种情况:当前位置是小于x的。比如123 0 7,这个情况下,当前位出现一的情况是0010~12219,只看高低位的话,000 0~1229因此是1230个。此时就是digit*high当前位置等于x。比如123 1 7,此原创 2021-03-28 22:32:03 · 448 阅读 · 0 评论 -
【leetcode经典题目】石子问题--最大最小问题的解析
文章目录1686. 石子游戏 VI1690. 石子游戏 VII以石子问题为代表的最大最小问题是leetcode经常出现的一类博弈论类型的题目。主要的思路贪心或者DP。1686. 石子游戏 VI特点:不是两侧取而是任取,评价标准是各自拿到的石子的和。对于这种任取的思路,相当于是对石子堆按照某种顺序进行排序,如果数据量很大的话,无法找到恨到的方法。因此很容易想到贪心策略。那么核心问题就是,如何贪心,按照什么进行贪心。两个路径:对于同一块石子,两个人的权重不同,要不让va[i]-vb[i]最大,要不让原创 2020-12-17 11:22:14 · 1222 阅读 · 1 评论 -
【经典题目】LCP13. 寻宝——数位dp、旅行商问题
引言题目是力扣的年赛题目,很经典的一道题。融合了很多基础的知识。尤其是涉及到了旅行商问题。题目链接一定要想清楚,旅行商问题和其他的dijkstra算法等路径算法的区别。旅行商问题是给定起点,途径全部点,回到终点的最短距离。思路是采用数位dp。题目相对容易理解,我们需要明确一下思路。采用倒推答案,我们最后的目标是要求解找到一个最短路径,这个路径给定了终点和起点,要求途径全部的机关。因此其实是一个旅行商问题。需要用数位DP的方法。旅行商问题是给定了起点,求解途径全部中点的并回到起点的距离。我们这里给定原创 2020-07-30 15:32:25 · 1040 阅读 · 0 评论 -
【经典题目】最大异或对——二进制与Trie树
题目链接如果按照暴力的方法,进行两次循环可以解决:for i in range(N): for j in range(i+1, N): ans = max(ans,nums[i]^nums[j])这样操作的时间复杂度为O(n)O(n)O(n)还可以转化为二进制的问题,进而用Trie树解决。我们从最高位开始进行选择,尽量选择与目前这个数不同的位,这样可以保证异或最大。class Trie: def __init__(self): self.dic = {}原创 2020-07-13 15:48:19 · 202 阅读 · 0 评论 -
【经典题目】子数组的最小值之和——单调栈
hulu 原题思路是单调栈比如输入[1,3,2],初始dot = 0, ans = 0。首先,1入栈,dot += 1 * 1,这个加上的1对应区间为[1],ans += dot, ans = 1然后,3入栈,dot += 3 * 1 ,即dot = 4 = 1 + 3,这里的1对应的区间为[1, 3], 3对应的区间为[3],ans += dot,ans = 1 + (1 + 3),对应的区间为[1], [1,3], [3]最后,2入栈前将3弹出栈,弹出的时候dot -= 3 * 1, dot原创 2020-07-06 22:22:41 · 285 阅读 · 0 评论 -
【经典题目】最长连续序列——维护连续序列长
2020/06/26 难度H,题目要求求解最长连续的序列,这道题目的特点是如何把众多点连接成线,并且可以很方便的查询到每根线的两头。这里采用了利用两个字典构建左右端点的方法。这个方法可以作为一个模板方法,除了这一类串点成线的问题很方便。这个方法有一个关键在于,不能有重复的元素每次合适的更新左端点和右端点class Solution(object): def longestConsecutive(self, nums): dic_l = {} dic_r原创 2020-06-26 15:24:58 · 114 阅读 · 0 评论 -
【经典题目】最长回文子序列——斜向dp,区间dp
引言对dp问题进行具体的划分的话,是可以具体分为区间dp,前向dp,数位dp等等。之前我们写过的戳气球问题,其实也是一个区间dp问题,这类问题的特点在于状态的设计。给定dp[i][j]表示在区间[i, j]里面满足条件的个数。我们可以发现,最后需要求解是,dp[0][n-1]这个状态。并且对于dp[i][i]这个状态的情况我们是清楚的。可以用一个图很好的体现过程。图来自labuladong。可以看出,如果我们需要求解dp[i][j]我们首先需要得到的是dp[i+1][j], dp[i][j-1],原创 2020-06-19 18:29:38 · 180 阅读 · 0 评论 -
【经典题目】缺失的第一个正数——原地哈希表,维护连续序列长
来源于Leetcode的第41题, 难度H完成这个任务其实不算复杂,只需要使用set去重,然后依次查找。只是题目限制了算法复杂度和使用的空间。比较好的思路是借助数组的索引,实现原地的哈希表。对于数组中的数字,我们将该数组对应的索引的数字设置为负数,最后我们遍历整个数组,发现的第一个不是负数的数字的索引就是缺失的。这种方法我们首先需要进行预处理数组,将数组中小于等于0和大于n的数字都设为1,并且在处理索引时考虑,当数字为n对应到0的索引。最后考虑特殊情况,首先是考虑1是否在其中,其次是先从1开始检查原创 2020-06-19 15:09:19 · 162 阅读 · 0 评论 -
【经典题目】括号问题
引言括号问题是一类特殊的匹配问题,比较常见,常用的方法主要是dfs,dp,栈等方法,本文汇总这些题目进行分析。例题22.括号匹配难度是M,首先需要思考明白,如何才能做到不重不漏的得到全部(有效)的括号组合。第一个方法是dfs,首先我们明确如何得到有效的括号组合,要求的任何一个位置的右括号的数量都不能少于左侧括号。因此我们可以采用dfs的方法进行搜索。class Solution: def generateParenthesis(self, n: int) -> List[str]原创 2020-06-14 00:03:33 · 1718 阅读 · 0 评论 -
【经典题目】正则表达式匹配,通配符匹配——字符串的dp匹配问题
引言核心的dp状态设计还是老方法,但是给出了通配符这个新东西。因此要对这类操作有新的思考。其中涉及到了一个状态压缩的方法比较巧妙。题目思考,状态还是自然定义为dp[i][j],表示s[:i]和p[:j]匹配的情况。对于状态的转移我们考虑两种大的情况:p[j+1] == '*'这是一个特殊的情况,我们需要整体处理a*这种形式s[i] == p[j] or '.'此时是匹配的,可以化为dp[i][j] = dp[i-1][j-1]当p = '*' 有情况dp[i][j] = dp[i][j-2原创 2020-06-09 15:47:56 · 407 阅读 · 0 评论 -
【每日一题+经典】单词接龙II——通配符+bfs+dfs ++ 双向bfs
2020/06/07 返回搜索路径的BFS是一道典型的bfs题目,其实可以用回溯方法,但是复杂度太高。难点在于如何降低复杂度。首先是通配符的方法,构建了一个字典,键是通配符,对一个的值是所以符合这个通配符的单词。其次是结合了bfs和dfs的方法,bfs保证了找到最短的路径,同时在bfs中构建了一个后继字典,这样在dfs中可以方便的得到路径。后继字典的构建保证了不会有绕远的路径出现,因为有visited数组。from collections import defaultdictfrom coll原创 2020-06-08 17:57:02 · 178 阅读 · 0 评论 -
【经典题目】戳气球——dp问题的遍历方法
引言戳气球问题是dp问题中的一道经典问题,难度在于逆向的思维和复杂的dp遍历方法。题目链接添加链接描述题目设计状态和转移方程首先如果是正向思维,其实很难求解。难点在于定义状态,如何定义第i个和第j个气球已经被戳破的状态。我首先想到的方法是数位dp的方法,设置有n个二进制数字,初始化全1,如果扎破了该位就置0,这样是可以定义状态的。但是这道题目的n很大,很难进行实现。因此第一个难点出现了,考虑逆向的思维,开始添加气球。按照什么样的顺序添加气球才能够得到最大的金币。因此我们可以考虑这么一个子问题,原创 2020-06-06 15:52:44 · 573 阅读 · 0 评论 -
【经典题目】螺旋矩阵——矩阵的转置与旋转,zip函数
引言螺旋矩阵这道题目不是算法思想的题目,是一类相对单独的题目。学会处理矩阵的旋转和巧妙利用zip函数是重点。例题1首先给出最为直观的方法一,维护了四个变量,旋转着进行输出。需要注意一点range(from, to, step)这三个参数不要搞错了。class Solution: def spiralOrder(self, matrix: List[List[int]]) -> List[int]: if not matrix: return [原创 2020-06-03 00:38:17 · 307 阅读 · 0 评论 -
【每日一题】和为k的连续子数组——前缀和与滑窗
2020/05/15 每日一题对于要求连续子数组的题目,灵活使用前缀和和滑窗的方法。特点在于,前缀和是否递增。560.和为k的子数组题目需要注意几个关键点,数组元素是既有正数又有负数的,且要求是连续的子数组。数组元素既有正数又有负数隐含了意思,数组不是单调的。因此不适合用滑动窗口的方法。**滑窗特点是,固定了左边界以后,右边界找到了一个可行解以后,右边界再靠右边的更大的区间肯定不存在目标值,所以才将左边界继续向右滑。**在这道题里显然没有这个性质。其次,这里的连续子数组的限制给了我们采用前缀和的原创 2020-05-15 15:48:39 · 559 阅读 · 0 评论 -
【经典题目】二叉树最近公共祖先
2020.05.10每日一题十分经典的题目,也曾经是阿里的面试原题。这里再次总结。两种主要的核心思路,对于二叉树的问题。是否设计全局变量用于返回值。首先是不设计全局变量的方法。按照题意要求,就需要返回节点。我们需要注意是从下往上还是从上往下进行递归。我们首先判断返回条件。如果当前节点是p或者q,就返回当前节点,否则返回None。并且进行判断,因为是自上而下的递归,如果当前节点是p或q的一个。一定可以直接返回,因为子树种一定存在另外一个;或者出现了左右节点全部都返回值了,此时改为返回当前节点的值。因为这原创 2020-05-10 16:00:21 · 229 阅读 · 0 评论 -
【经典题目】只出现x次的数字——异或操作
只出现x次的数字–巧用异或入门级:只出现一次,其余数字出现了偶数次很简单了,直接利用异或的性质,每次将数组所有数字的异或在一起,因为其他数字都出现了偶数次,所以异或结果就是唯一的奇数次的。class Solution: def singleNumber(self, nums: List[int]) -> int: ans = 0 for i i...原创 2020-05-06 17:35:52 · 120 阅读 · 0 评论 -
【经典题目】rand7()生成rand10()——随机数算法
随机数算法的转换从小数向大数映射这一类的算法主要分为两种,一种是从小数映射向大数,rand7()-->rand10()。另外一种是从大数映射向小数rand10()-->rand7()这道题目是从小数映向大数,核心公式(rand7()−1)∗7+rand7()(rand7()-1)*7+rand7()(rand7()−1)∗7+rand7(),也就是生成0-6的数字,然后放大7倍...原创 2020-05-06 16:18:39 · 1191 阅读 · 0 评论 -
【经典题目】分割数组的最大值——巧用二分法
来源于竞赛 难度H二分法的思路:存在一个bound,大于或小于这个bound都无法满足条件。查找这个bound分割数组的最大值这道题有一个很有意思的方法,就是二分方法。之所以能采用二分去思考的本质原因在于:具有单调最优的性质:如果最大值为 t 可以满足条件划分,那么最大值为 t+1也可以,所以就直接二分最大值 t,找到最小满足条件的 t 即可。class Solution: de...原创 2020-05-06 01:56:16 · 393 阅读 · 0 评论 -
【经典题目】有序矩阵中的第 k 个最小数组和——分析题目的思路,有序矩阵的处理
第187周竞赛 难度H是一道考察解决问题的思路的题目,如何优化问题是关键。首先可以采用暴力的方法,从上往下依次进行计算。也就是首先计算第一行的各数,然后将第一行的各数加上第二行的各数得到mm个数字,进行排序取前k个。然后对这k个数字与第三行的数字在依次进行相加,得到km个,取前k个。知道到达最后一行。时间复杂度:O(n∗(k∗m+klogk))O(n*(k*m+klogk))O(n∗(k...原创 2020-05-04 00:05:24 · 457 阅读 · 0 评论 -
【经典题目】绝对差不超过限制的最长连续子数组——滑动窗+单调栈
183周竞赛题目 难度M也是一道将动态规划问题转换为单调栈的问题。借助这道题目我们希望得到一些启示,什么样的题目是适合考虑单调栈。首先单调栈的核心是维护了一个递增或递减的队列。也就是很容易得到在一定范围的最大值的坐标。对于这道题目,最大的最大值的差无疑就是要求在一定范围内的最大值和最小值之差。因此我们需要一个队列去维护在一定范围内的最大值和最小值。对于一定的范围这个限制,结合题目中连续子...原创 2020-05-03 16:23:05 · 349 阅读 · 0 评论 -
【经典题目】每个人戴不同帽子的方案数——从人对应物品到物品对应人的转换思路
第25场双周赛第四题这道题可以按照回溯法的思路暴力结局,列举出来所有的可能佩戴方法。但是这种方法的复杂度较高,并不是最优解。这里我们换一种思路,同样是回溯法,相比于给每个人佩戴帽子,每个人都有很多种选择,不如把问题转变成给帽子选择人。一共40顶帽子,每一个帽子都分为有人戴和没人戴。且只能被一个人拥有。因此我们考虑考虑变成背包问题,首先依次遍历40顶帽子(戴or不戴),在内层循环中遍历每一个...原创 2020-05-03 15:14:18 · 673 阅读 · 0 评论 -
【经典题目】网络延迟时间——dijkstra算法
来源leetcode743题dijkstra算法是图算法中的一种经典算法用于解决单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。需要注意这种算法要求不能存在负权边。 属于一种贪心算法1)算法思想:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点...原创 2020-05-01 23:28:54 · 643 阅读 · 0 评论 -
【经典题目】可获得的最大点数--从dp问题变成滑动窗问题
183周周赛题目难度只是M,看到题目,很像拿石子那个题目。首先想到利用DP.。为简单起见,采用带备忘的dp方法。class Solution:# dp 自上而下的 def __init__(self): self.dic = {} def maxScore(self, cardPoints: List[int], k: int) -> int: ...原创 2020-04-27 00:02:16 · 156 阅读 · 0 评论 -
Leetcode 110 平衡二叉树(从底至顶,与从顶至底,递归思想及合理剪枝)
Leetcode 110 平衡二叉树(从底至顶,与从顶至底) 题目难度:简单又一次被二叉树问题绕进入了,对于二叉树的高度和深度的编写一直是问题。因此以本题为例分析一下二叉树的深度与高度问题。从底至顶(提前阻断)此方法为本题的最优解法,但“从底至顶”的思路不易第一时间想到。思路是对二叉树做先序遍历,从底至顶返回子树最大高度,若判定某子树不是平衡树则 “剪枝” ,直接向上返回。算法流程...原创 2020-03-17 12:33:31 · 196 阅读 · 0 评论 -
【动态规划专题】字符串匹配,编辑距离
字符串匹配问题是dp问题中一类一种经典问题,包括了最长匹配字符串,和编辑距离等。我们以编辑距离为例之所以将这几个问题放在一起讨论,因为都是有相同的dp设计思路,和状态转移方程的设计。状态设计思路:二维矩阵dp[i][j]表示word1前i个字符与word2的前j个字符下的子问题,在本问题中就是代表 word1 到i位置转换成 word2 到j 位置需要最少步数。状态转移方程:如果wor...原创 2020-04-06 17:17:03 · 357 阅读 · 0 评论 -
leetcode 139 单词拆分(dp)
139 单词拆分首先想到这是一道可以用dfs解决的题目,但是dfs会超时,时间复杂度极高。如果题目没有要求给出具体的路径,能用dfs解决的题目一般都可以用dp解决。只是这个题目的子问题有点奇怪,因此没有考虑好。子问题:以s[i]结尾的字符串是否满足题意状态:dp[i]对应每个子问题状态转移: dp[i] = dp[x] and s[x:i] in dic也就是说,前一段满足状态,且后一...原创 2020-03-31 21:05:23 · 235 阅读 · 0 评论 -
leetcode 114 二叉树展开为链表
二叉树展开为链表又是一道二叉树的题目,以后我做一道写一道。不信不能ac二叉树。这个题目比较简单,就是让二叉结构变成全是右侧子树。个人总结递归和迭代这两种方法其实是思考方法不同。递归:讲究的是从小见大,每次都是完成最基本的操作,最后整体的操作水到渠成。迭代:从上到小,要完成大的目标,先完成根的处理。这个题目首先还是需要想明白如何实现的链表化,其实核心在于让右子树连接到左子树的最右侧节点...原创 2020-03-31 19:10:43 · 170 阅读 · 0 评论 -
leetcode 98 验证二叉搜索树
验证二叉树二叉树的题目好难啊,思路不是很清晰。首先分析这个题目,BFS树要求右子树的所有节点都大于当前节点值,左子树的所有节点都小于当前节点。想一下,右子树的最小值,应该是右子树的最最最左侧的一个叶节点,左子树的最大值应该是最最最右侧的叶节点。从下往上似乎不好比较。如果我们只是考虑每一个小的二叉树。也就是只有三个节点的。什么情况下才是bfs呢?右子树是bfs左子树是bfs当前节点值...原创 2020-03-30 22:31:14 · 88 阅读 · 0 评论