leetcode
haikuc
这个作者很懒,什么都没留下…
展开
-
99. 恢复二叉搜索树
Morris遍历中序遍历可以理解为从根节点先往左边走,走到最左边,然后往上走,再往右。同一个结点第二次经过的时候,输出这个结点的值。Morris利用叶结点left和right的NULL实现了上述过程,通过right记录下一个要走的结点。记cur为当前走到的结点,如果是第一次走到,那么让cur的左子树的最右结点的right指向cur,否则就把cur的左子树的最右结点的right重新置为NUL...原创 2019-12-01 12:54:00 · 79 阅读 · 0 评论 -
84. 柱状图中最大的矩形
每个柱子可以伸展最远的距离为左边第一个低于它的柱子和右边第一个低于它的柱子,所以如果能记录每个柱子上述两个值,就可以解决问题了。建立堆栈s,s压入-1从左往右遍历heights数组,记索引未i。1.如果s中只有-1,或者heights[i]>=heights[s.top()],压入i。2.否则,弹出s栈顶的下标k,以heights[k]为高度的矩形最大为heights[k] * ...原创 2019-12-01 12:27:23 · 82 阅读 · 0 评论 -
76. 最小覆盖子串
记L,R为当前检查子串的最左端和最右端。1.刚开始让L和R为0。2.然后R一直往右,直到找到第一个满足要求的子串。记录此时的子串长度。3.让L往右,直到子串第一次不满足要求,记录这个过程中最短的满足要求的子串长度。4.此时的子串是不满足要求的,重复第2,3步骤。class Solution {public: string minWindow(string s, string t...原创 2019-12-01 12:01:42 · 129 阅读 · 0 评论 -
75. 颜色分类
设L,R为左右第一个不符合要求的点。cur为当前遍历的点,遍历顺序为从左往右。当num[cur]==1时,cur++。当num[cur]==0时,交换cur和L对应的数,然后cur++,L++。当num[cur]==2时,交换cur和R对应的数,R–。如果cur>L,说明L指向的数肯定是1,所以当num[cur] == 0时,交换cur和L后,两者都要++。如果cur==L,如果n...原创 2019-12-01 11:47:25 · 108 阅读 · 0 评论 -
45. 跳跃游戏 II
贪心每一步都挑选下一步能达到的最远距离。2,3,1,1,41 2 3 4 5以下数字指代下标1-5.第一次可以跳到下标2或者3,如果跳到2,下一步最远可以跳到5,如果跳到3,下一步只能跳到4,所以这一次选择跳到2。如果某一步的最远距离跨过了5或者到达了5,说明可以跳到终点。本题已经说了肯定可以跳到终点,那就只要按照上述过程算出跳的次数就好了。end代表某一步跳的范围,比如刚在1上就是...原创 2019-11-24 12:03:15 · 85 阅读 · 0 评论 -
42. 接雨水
双指针法基本思路是找每一列左边最大值Lmax和右边最大值Rmax,如果min(Lmax,Rmax)大于该列高度h,那么就可以蓄水h-min(Lmax,Rmax),否则不能蓄水。如果维护两个数组来记录每一列的Lmax和Rmax,那就可以在O(1)时间内得到这两个值了,但是需要额外的空间。双指针法就可以优化这部分额外的空间。用left和right标记两个指针,lmax和rmax标记left左边的...原创 2019-11-24 11:49:25 · 105 阅读 · 0 评论 -
41. 缺失的第一个正数
1.检查有没有12.记数组长度为n,把所有大于n和小于1的数去掉。具体操作:把所有小于1的数变成13.从左往右遍历数组,如果数字a大于n,略过,否则就把数组第a-1个元素变成负的。4.从左往右遍历数组,找到第一个正数,对应下标+1就是答案了。其实就是用正负号代表数字有没有出现过,这样就不用额外空间了。class Solution {public: int firstMissin...原创 2019-11-24 11:38:04 · 66 阅读 · 0 评论 -
32. 最长有效括号
1.栈刚开始压入-1,当遇到(的时候压入对应的下标,遇到)的时候pop一个栈的元素,当前下标减去栈顶元素就是以当前)结尾的子串的最长匹配长度。正确性:栈中存的是第一个能够匹配的子串的起始下标-1。如果当前的串一直能够匹配比如()(),或者((())),那么栈始终不可能为空。但是如果)的数量大于了(,比如())(),那么就要把当前不匹配的)的下标压入栈,它就成为了新的匹配子串的前一个下标。#i...原创 2019-11-24 11:32:51 · 85 阅读 · 0 评论 -
31. 下一个排列
从右往左找第一个num[i-1]<num[i]的i。此时从i到最右边是从大到小排列的,从右往左找第一个num[j]>num[i-1],交换i-1和j对应的数。此时从i到最右边仍是从大大小排列,倒序,变成从小到大。#include<algorithm>class Solution {public: void nextPermutation(vector<...原创 2019-11-21 11:41:46 · 106 阅读 · 0 评论 -
30. 串联所有单词的子串
滑动窗口所有words中单词总长度一定,记ttlen。在s中从下标 i 开始取ttlen个字符,统计每个单词出现的次数,如果和words一样,就把起始下标i加入答案。记每个单词的长度为len,从i开始字符串和从i+len开始的字符串大部分是一样的,只是少了s[i+1,i+len),多了s[i+ttlen,i+ttlen+len)。#include<unordered_map>...原创 2019-11-21 11:35:33 · 117 阅读 · 0 评论 -
29. 两数相除
不考虑边界情况下,a/b=x1 * b + x2 * b + x3 * b …x1,x2,x3是以2为底的幂,1,2,4,8…整体过程:b一直左移直到小于a,记移动的位数为n。此时x=1<<n。a-=b<<n。重复上述过程直到a<b,所有的x之和就是答案。由于int最小值是-INT_MAX-1,最大值是INT_MAX。所以不能直接用abs取绝对值,把两个数...原创 2019-11-21 11:28:51 · 417 阅读 · 0 评论 -
15 三数之和
双指针法先按非降序排序。i遍历1-N-2,对应于每个i,L从i+1往右滑动,R从N往左滑动,如果nums[i]+nums[L]+nums[R]<0,L往右移动,不然R往左移动。得到一个正确答案后,L和R都要越过所有重复的值,i也要往右移越过所有重复的值。class Solution {public: vector<vector<int>> three...原创 2019-11-21 11:12:24 · 76 阅读 · 0 评论 -
11 盛最多水的容器
双指针法i从0开始往右边移动,j从最右往左移动。如果i对应的板子比j对应的高,那么往右移动i只可能让面积越来越小,因为距离变小了,并且短板的高度不可能变大。所以此时就要把j往左边移动才可能得到更大的答案。class Solution {public: int maxArea(vector<int>& height) { int i=0,j=hei...原创 2019-11-21 11:08:01 · 76 阅读 · 0 评论 -
10 正则表达式匹配
记文本串S,模式串P,dp(i,j)表示从i开始的S和从j开始的P是否匹配。判断从S[ i ]开始的文本串和从P[ j ]开始的模式串能否匹配的过程如下:1.判断S[ i ]和P[ j ]是否相等,结果记f(bool)。2.如果P[ j+1 ]=‘*’,那么有两种情况。第一种是忽略P[ i ]和P[ i+1 ],即代表0个P[ i ]。dp(i,j)= dp(i,j+2)。第二种是P[ ...原创 2019-11-18 15:21:35 · 98 阅读 · 0 评论 -
4寻找两个有序数组的中位数
一个更普通的问题:寻找第k个数。记两个数组为A,B。比较mid1 = A[k/2]和mid2 = B[k/2],如果前者比较小,那说明A[k/2]肯定小于要找的第k个数。如果数组B的size小于k/2,那相当于mid2 = INT_MAX。接下去就从剩下的A和全部的B中找第k-k/2个数。特殊情况:k=1,只要比较两个数组的第一个数;有一个数组为空,只要从另一个数组中取第k个数;以上两...原创 2019-11-17 16:35:50 · 92 阅读 · 0 评论 -
5 最长回文子串 dp & 马拉车
dpdp[ i ][ j ]代表从i开始到j结束的字符串是否是回文的。状态转移dp[ i ][ j ] = dp[ i +1][ j - 1 ] && s[i]==s[j]。时间复杂度O(N*N)class Solution {public: string longestPalindrome(string s) { if(s.size()==0) ...原创 2019-11-17 16:15:02 · 86 阅读 · 0 评论