![](https://img-blog.csdnimg.cn/20201014180756925.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
LeetCode刷题笔记
文章平均质量分 54
头发没了还会再长
你不需要很厉害才开始,但你要开始才能很厉害
展开
-
LeetCode最短无序连续子数组
题目:来自LeetCode一个数组有序,那么左边的数一定小于右边的数,如果一个数组部分有序,就说明这个平衡在某个地方被打破了,从左向右遍历,如果nums[i]小于左边的max,则说明位置i的元素需要调整,用right保存这个值,遍历整个数组,一直到最后,不断的更新right的值,那么遍历结束得到的下标就是最后一个需要调整的位置,同理,从右向左遍历,如果nums[i]大于右边的最小值,这说明位置i需要调整,用left来保存这个值。最后right-left+1就是要调整的数的长度。int fi..原创 2021-12-09 22:17:22 · 233 阅读 · 0 评论 -
LeetCode.239.滑动窗口最大值(单调队列)
题目描述:来自LeetCode思路:由示例1可以看出,每次求滑动窗口的最大值其实就是从当前窗口的k个元素里找到一个最大值,但如果每次都去遍历一下滑动窗口的里各个元素的值,时间复杂度就会变高。这里,我们用单调队列来优化。单调队列一般都是用来优化最大最小值问题,每次往队列里加入元素的时候,我们都要保证队列在添加完元素之后依旧具有单调性,这样我们在取最大最小值的时候,只用从队头取,时间复杂度只有O(1),且每个元素只会入队出队一次,故时间复杂度是O(N)的。如果我们想要每次都从队头取出一个最大值.原创 2021-11-14 21:48:15 · 710 阅读 · 0 评论 -
LeetCode 234.回文链表(快慢指针+反转单链表)
题目描述:来自LeetCode思路:回文链表就是链表两边关于中间对称,那如果对称就是回文链表了,想要判断两边是否对称就要对两边一一比较,所以第一件事就是要找到中间结点,如何确定中间结点的位置?快慢指针呀!快指针每次走两步,慢指针每次走一步,当快指针都到链表最后的时候,慢指针走到中间结点。如何比较呢,因为是关于中心对称,所以前面的从左往右和后面的从右往左是一样的,那我们可以就可以将后面的链表逆序,然后得到后面链表逆序之后的首结点,就可以和前面的链表开始比较了。还有关于链表结点个数是奇还是偶的问题,如.原创 2021-11-13 20:26:58 · 798 阅读 · 0 评论 -
LeetCode.数组中的第k个最大的元素(基于快速排序的选择排序算法)
题目描述:来自LeetCode思路:快速排序的时间复杂度是O(NlogN),但是基于快速排序的选择排序算时间复杂度只有O(N)。快速排序:就是找到一个枢轴,将枢轴左边比枢轴大的数都移动到枢轴右边,枢轴右边比枢轴小的数移到枢轴左边,再对左边和右边分别用同样的方法排序,最后得到一个有序的数组。而快速选择找到第k大的数或者第k小的数,我们并不用每次都将两边排序,我们只用排序k所在的一边就行。比如说第一次排序之后,数组左边的数一定全部小于右边,即使我们再对左边和右边进行排序,在左边的数还是在左边,在右边..原创 2021-11-08 22:41:44 · 499 阅读 · 0 评论 -
LeetCode.200.岛屿数量(DFS&&BFS)
题目描述:来自LeetCode方法一:深度优先搜索可以将矩阵看成一个图,进行图的深度优先搜索,每两个相邻的‘1’可以看成是有一条边,在学数据结构的时候,我们知道,连通图进行深度优先遍历的时候,只会搜索一次,非联通图有几个联通分支就会遍历几次,巧了!这个题的意思其实就是让求联通分支的个数啊!!所以对遍历二维矩阵,进行深度优先遍历,每dfs一次,就记录将记录岛屿数量的变量+1,遍历的过程,要将遍历过的数据进行标记,在这里,将‘1’修改为‘2’即可。dfs结束的条件就是判断数组是否越界,或者该位.原创 2021-11-06 22:58:48 · 201 阅读 · 0 评论 -
LeetCode198.打家劫舍(动态规划)
题目描述:来自LeetCode思路:这道题和01背包很像,这件房屋偷不偷跟前一间房屋是否偷了有关,比如说这是第i间房屋,如果第i-1间房屋偷了,那第i间房屋就不能再偷,那最大值就跟前i-1间房屋的金额最大值有关,如果第i-1间房屋没偷,那第i间房屋就可能要偷,且最大值跟前i-2间房屋有关,每一天偷与不偷,都跟前面的最大值有关,故可写出状态转移方程dp[i]=max(dp[i-1],dp[i-2]+nums[2]),特殊的,当只有一间房屋,则一定偷,且最大值为dp[0]=nums[0],当只有两件房.原创 2021-11-03 22:58:18 · 5139 阅读 · 2 评论 -
LeetCode.相交链表(两种解法)
题目描述:来自LeetCode解法一:思路:假设相交,两个指针同时走,相遇的条件是什么呢,自然是两个指针走了同样的步数,但两个链表相交之前的结点个数不一定相等,怎么样才能让两个指针走相同的步数呢?那就让两个指针都遍历一遍自己的和对方的链表,这样在遍历完当前链表去遍历另一个链表的时候,两个指针一定会相遇ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { if(headA==NULL||headB.原创 2021-11-02 23:37:25 · 270 阅读 · 0 评论 -
LeetCode.152.乘积最大子数组(动态规划)
题目描述:来自LeetCode思路:正数*正数=正数,正数*负数=负数,负数*负数=正数,所以要分两种情况来讨论当第i个数是正数时,且前i-1个数乘积是正数 或者 当第i个数是负数,且前i-1个数乘积是负数,以第i个数结尾的乘积最大子数组一定是*第i个数当第i个数是正数时,且前i-1个数乘积是负数 或者 当第i个数是负数,且前i-1个数乘积是正数数,以第i个数结尾的乘积最大子数组一定是前i-1个数的乘积故我们需要记录负数的同时也要记录正数,如果第i个数是负数,前面的乘积也是负数,那肯定原创 2021-10-21 21:40:52 · 90 阅读 · 0 评论 -
LeetCode.最长连续序列(哈希表)
题目描述:来自LeetCode思路:可能第一想法是排序,反正我是,但是排序,快排的时间复杂度是O(NlongN)的,题目要求用O(N)时间复杂度,所以只能是遍历一边数组求解。遍历数组的时候,如果连续序列是从这个数开始的,说明说明呢?说明这个数的前一个数不存在!那么我们就要把这个数当做这个序列的第一个数,看这个数+1是否存在,+2是否存在...不存在了我们就更新最大值。那连续序列不是以这个数开始的条件是什么呢?那这个数-1的数一定存在,这样连续最长序列一定是从这个数-1的数开始的,所以这样就不用求这个数.原创 2021-10-17 22:51:28 · 98 阅读 · 0 评论 -
LeetCode.买股票的最佳时机(动态规划)
题目描述:来自LeetCode方法一:暴力解(会超时)思路:遍历数组,从第二天开始只要满足条件,我们都可以选择卖出,而买入的时间自然可以是卖出前的任意一天,所以用一个变量来保存最小值,在遍历的时候,外层循环遍历数组更新可以获得的最大利润,内层循环用来更新第i天卖出,哪一天买入可以获得的最大值。代码实现c++:class Solution {public: int maxProfit(vector<int>& prices) { int m.原创 2021-10-17 22:21:47 · 186 阅读 · 0 评论 -
LeetCode.105.从前序遍历与中序遍历序列构造二叉树
题目描述:来自LeetCode思路:首先要知道前序遍历和中序遍历,前序遍历即先访问根节点,再访问左子树,最后访问右子树,而中序遍历即先访问左子树,再访问根结点,最后访问右子树,所以前序遍历的第一个节点一定是根结点,在中序遍历中,根节点左侧的序列一定是左子树,右侧一定是右子树,在确定了左子树和右子树的范围后,在前序遍历中就可以确定左子树的根结点(就是前序遍历的左子树序列的第一个结点),右子树的根结点(就是前序遍历的右子树序列的第一个结点),然后再通过确定的根结点在中序遍历里划分左子树和右子树,..原创 2021-10-15 23:53:06 · 136 阅读 · 1 评论 -
LeetCode 55.跳跃游戏(贪心,逆向思维)
题目描述:来自LeetCode方法一:思路: 基于贪心的思想,我们可以计算每一个可以到达的位置所能到达的最远的距离,并不断更新这个最远距离,因为可以选择走的更远的我们当然不选择近的啦。(可以将数组长度想象成一段路程,数组上的点代表加油站,每一个值代表在该加油站加完油后可以行驶的最远距离,如果在这个加油站加完油之后可以走更远,我们就加油,如果不能,我们当然不加了,并且选择在该加油站加油的前提条件是能到达该加油站,不然....怎么加)如果最远距离大于等于数组长度,则返回true,否则返回false。原创 2021-10-14 22:49:20 · 1076 阅读 · 0 评论 -
LeetCode 96不同的二叉搜索树(动态规划)
题目描述:LeetCode官网思路:可能会很自然想到递归来写,但递归有很多重复计算,树的建立是一个递归过程,但同时也是将大问题转化成一个个子问题来解决的,可以考虑动态规划,就像递归建立二叉树一样,我们可以让任意一个结点当做根结点,这样每次的二叉树都是不一样的,至于每一个节点做根结点会产生有多少种树呢?假设n=3,当1为根结点时,2 3只能是它的右子树上的结点,左子树上就没有结点,而2 3的排列又由2 3哪一个先创建来决定,即每一个结点其实既是孩子结点又是根结点,而且子树的建立跟树的建立是相同的,故.原创 2021-10-13 23:22:32 · 112 阅读 · 0 评论 -
LeetCode 141.环形链表
题目描述:来自LeetCode方法一:hash表 我们很容易想到这种遍历然后做标记的方法来判断是否遍历过,如果遍历过又回到了这个节点,那就一定存在环,可以用hash表存储,在java里HashSet存储的元素不可重复,当某个元素在hash表里已经存在就会返回false并且不存储,(关于HashSet可以看看我的这个博客HashSet存储元素唯一性源码分析),那我们一边遍历一边将结点放入集合,如果失败就说明该元素已经存在,则是环形链表。在C++里有一个unordered_set,该...原创 2021-10-12 22:16:35 · 81 阅读 · 0 评论 -
LeetCode 79.单词搜索(dfs+剪枝)
题目描述:来自LeetCode思路:看到这种搜索问题,很快就能想到dfs,以矩阵的每一个元素为起点和字符串的第一个元素为起点分别dfs,当我们遍历到字符串的最后一个字符也相等了,就说明word存在于网格中,故dfs要有一个参数m记录此时遍历的字符串的位置,将board和word也作为dfs函数参数,还有此刻遍历的矩阵的位置,我们用i,j来表示此时遍历到第i行第j列,题目里还有说同一个单元格的元素不能被重复用,故我们还要有一个标志单元格的元素是否被使用的标记数组。然后就可以开始dfs了,单元格的元原创 2021-10-11 23:27:08 · 229 阅读 · 0 评论 -
LeetCode 78.子集
题目描述:(来自LeetCode)思路:对于每一个数组里每一个数,我们可以选择加入和不加入当前集合,n个数就有二的n次幂种可能。我们遍历数组中的每一个数,加入哪个集合呢?应该是所有已经存在的集合!!!比如:数组:[1 2 3] 用num存当前的集合,res存所有已经存在的集合1.res里面只有一个集合,该集合num是个空集 res[[]]2.然后遍历数组,将res中所有已存在的集合拿出来与1组成新的集合,就是[]+1=[1],此时res[[],[1]]3.再遍历数组下一个元素2..原创 2021-10-10 22:52:55 · 53 阅读 · 0 评论 -
LeetCode 72.编辑距离(动态规划)
题目描述:(来自LeetCode官网)解题思路:将word1变成word2,对于每个字符,我们可能进行的操作有三种,增删改,但去暴力枚举每一个的话,时间复杂度过高,用动态规划去优化。对于状态规划,要确定两点,状态表示和状态计算首先:状态表示 (1)确定维度一般先从一维开始考虑,维数越高意味着复杂度可能相应的加一个维度,这道题要用状态表示两个字符串,一维很难进行两个字符串的判断,因此用二维来表示。f[i][j] (2)确定状态代表的集...原创 2021-10-09 23:50:08 · 138 阅读 · 0 评论 -
LeetCode.最小路径和(动态规划,状态压缩)
题目描述:(来自LeetCode)思路:用dp[i][j]表示从[0][0]走到[i][j]这一格的最短路径和,在起点dp[i][j]=grid[0][0]的,当在第一行和最后一列的时候,比较特殊,到达第一行某一个一定是从左侧过来的,到达第一列某一格,一定是从上面过来的,因为只能向下和向右走,因此,我们可以得到动态转移方程当i>0且j=0时,dp[i][0]=dp[i-1][0]+grid[i][0]当j>0且i=0时,dp[i][0]=dp[0][j-1]+grid[0][j]原创 2021-10-07 23:56:17 · 262 阅读 · 0 评论 -
LeetCode 62.不同路径(动态规划/组合数)
题目描述:(来自LeetCode官网)1.用动态规划求解思路:从左上角走到右下角,每一次可以选择向下走或者向右走。用dp[i][j]表示走第i行第j列这个格子的路径数,而走到这个各自可能是从上面走过来的也可能是从下面走过来的,那么走到这一步的路径数就是dp[i-1][j]和dp[i][j-1]的路径数的和,但是,有两种特殊情况,就是在第一行或者第一列的格子,我们都只有一种可能到达的路径,让dp[0][j]和dp[i][0]等于1就是,class Solution {public: ..原创 2021-10-06 23:38:24 · 106 阅读 · 0 评论 -
KMP模式匹配算法+ACwing831KMP字符串
题目描述:(来自ACwing)什么是KMP模式匹配算法呢?模式匹配算法是很低效的,于是有三位前辈,D.E.Knuth、J.H.Morris、V.R.Pratt发表一个模式匹配算法,可以大大避免重复遍历的情况,我们把它称之为克努特—莫里斯—普拉特算法,简称KMP算法。朴素模式匹配算法的复杂度是O(N*M),但KMP模式匹配的时间复杂度是O(N),因为n(主串的长度)不需要回溯,要进行匹配的串不停的移动和主串对比,匹配串也不用每次都从头开始比,而是先对匹配串计算出next数组,用next数组..原创 2021-10-05 23:18:24 · 118 阅读 · 0 评论 -
ACwing842.全排列+LeetCode46.全排列(dfs+回溯)
ACwing842.全排列先引入这个全排列理解一下如何递归和回溯的(可以在本子上画画,或者一步步调试看看)题目描述(来源ACwing):思路:1 2 3全排列,我们肯定会怎么排1 2 3,1 3 2,2 1 3,2 3 1,3 1 2,3 2 1,其实写成代码就是一个回溯的过程,1 2 3全部排完我们就输出,然后回退到1 2,三已经选过,再回退到1,此时2 也已经选过,我们选3,然后选2,1 3 2排完我们再输出再继续回溯,一回到数组全部遍历结束并且此时已经全部选过,那我们既要有一个数组来.原创 2021-10-04 23:03:18 · 170 阅读 · 0 评论 -
LeetCode39.40组合总和(dfs+回溯)
39.题目描述(来源LeetCode)思路:像这种求可行解的一般会想到要用回溯算法,回溯的过程记录可行解,不合适就回退一步,换一条道继续搜,继续回溯,对于每一个数,在每次搜索的时候有两种情况,加入可行解数组和不加入。...原创 2021-10-03 22:54:49 · 93 阅读 · 0 评论 -
LeetCode.在排序数组中查找元素的第一个和最后一个位置(附带二分判断边界的模板,y总教的嘿嘿嘿)
题目描述:来源(LeetCode热题100第34题)给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target,返回[-1, -1]。进阶:你可以设计并实现时间复杂度为O(log n)的算法解决此问题吗?示例 1:输入:nums = [5,7,7,8,8,10], target = 8输出:[3,4]示例2:输入:nums = [5,7,7,8,8,10], targe...原创 2021-10-02 20:03:23 · 85 阅读 · 0 评论 -
LeetCode 搜索旋转排序数组
题目描述:(来源LeetCode,热题100的第33题)整数数组 nums 按升序排列,数组中的值 互不相同 。在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为[4,5,..原创 2021-10-01 21:53:15 · 67 阅读 · 0 评论