1 Array
第五十四题: Spiral Matrix
本题可以设置一个top,bottom,left,right 等通过++,--来改变边界。
注意:1 if(matrix.size()==0) return res;
2 if(top>bottom) break;if(left>right) break;
3 定义:vector<vector<int>> matrix(3,vector<int>(4,0));
第五十九题:Spiral Martrix II
本题和上题类似,注意的是赋值 vector<vector<int>> matrix(m,vector<int>(n,0));
第七十三题: Set Matrix Zeros
本题要求in_place,遍历四次,第一次用vector存为0的i,第二次用vector存为0的j,第三次把i置为0,第四次把j置为0.
第七十五题 Sort Colors
1.计数排序,两次遍历;2一次遍历,遇到0,交换nums[red++] 遇到2,交换nums[blue--]
第八十题:Remove Duplicates from Sorted Array II
本题 注意if(m==0||m==1) return m;在无关定义之前可以加快速度。本题需要比较上一个数字和下一个不同的数字之间的距离。
答案用的2P, per 为存的值,cur为当前值。
第八十四题 Largest Rectangle in Histogram
本题 可以用stack,也可以用两个循环: for(int i=0;i<m;i++) for(int j=i,j>=0;j--) 当 height[i]<=height[i+1] continue; 短又小。
可以用单调栈,见答案解析,找到左起第一个小的数(单增栈),左起第一个大的数(单减栈)。
第八十八题: merge sorted array
从尾部向前merge,b长的话最后再处理b,a已经放进去了
2 String
第五十八题: length of Last Word
本题太简单 不说了
第六十八题:Text justification
要考虑i==n-1 的情况,比较繁琐,看代码:
第七十一题: Simplify Path
s.substr(x,y):x为起始位置,y为个数
本题目应该是用栈的,但是时间空间都不理想。用vector<string> 来将/ 和/(或者结尾)之间的数来放入,/../ 的时候pop,/./的时候略过。
3 backtracking
第五十一题,N-Queens本题明显回溯法: 首先主函数->DFS函数->valid函数
注意:1. DFS函数为void类型,开始先设定退出部分,后面是主体部分;
2. 本题vlid函数用多个if语句判断会超时,因此用pos来记录,abs(row-i)==abs(col-pos[i])判断四角部分无Q,见pad答案;
3. memory 用vector<string>res1(n,string(n,'.'));来解i
第五十二题,N-Queens II
本题和上题类似,直接改接口即可。
第七十七题 Combinations
本题经典bt, 需要加入一个level值表示put的数值,for(int i=level;i<=n;i++) ,再递归调用。
第七十八题 Subsets
本题和上题雷同。
第七十九题 word search
此题经典 bp 注意1,空集合判断;2.加上一个visited,表示之前用过没;
第九十题 Subsets II
本题经典dp, 注意重复值跳过。
4.DP
第五十三题 Maximum Subarray
numscur=max(numscur+nums[i],nums[i]); (想象一下滑动窗口,该滑动窗口并不是加一去一,而是两头不一定都变,有时候滑动的时候会去掉前面的负值,直接当前值为numscur,没必要用窗口了)
res=max(numscur,res);//numscur 是当前i为结尾的最大值
第六十二题:Unique Paths
dp[i][j] = dp[i-1][j] + dp[i][j-1]; 用一维数组占空间更小,一行一行 刷新:dp[j]+=dp[j-1];
第六十三题目:Unique Paths II
本题初始值要设置为0,因为有的路无法走通,第一个数看情况设置0或1.dp[i][j]=dp[i-1][j]+dp[i][j-1];
第六十四题:Minimum Path Sum
dp[i][j] = min(dp[i-1][j],dp[i][j-1]) + grid[i][j];
int dp[m][n];//vector<vector<int>> dp(m,vector<int>(n,0));节省了空间 vector容器预留了一些额外的存储区,用于存放新添加的元素,这样就不必为每个新元素重新分配整个容器的内存空间。
第七十题 Climbing Stairs
dp[i]=dp[i-1]+dp[i-2]; 注意初始状态 dp[0]=1,dp[1]=2
第七十二题 Edit Distance
int dp[m+1][n+1]; dp[0][j] = j;dp[i][0] = i;
if(word1[i-1] == word2[j-1]) dp[i][j] = dp[i-1][j-1];
else dp[i][j] = min(dp[i-1][j-1],min(dp[i][j-1],dp[i-1][j]))+1;
第八十五题 Maximal Rectangle
本题用一个很难想到的算法,将每一行之前的数看作是一个直方图,算最大矩形面积。
1.每个行直方图的高作为dp,下一行在上面加1,如果有值得话,否则为0.
2.算出直方图的高以后,求直方图的最大矩形,用到八十四题,遍历数组,找到一个局部峰值,然后向前遍历所有的值,算出共同的矩形面积,保留最大值。
注:当当前的dp值小于前面时(只是一个计算次数少的条件而已),开始while(好几次)算矩形大小,当前值不算(j-s.top-1).
第八十七题 Scramble String
本题可以用递归和dp两种方法,核心就是找到公式:
1.递归: isScramble(s11,s21) && isScramble(s12,s22) 和 isScramble(s11,s21) && isScramble(s12,s22)
注: s1和s2是scramble的话,那么必然存在一个在s1上的长度l1,将s1分成s11和s12两段,同样有s21和s22,那么要么是s11和s21是scramble的并且s12和s22是scramble的;要么s11和s22是scramble的并且s12和s21是scramble的。
2.dp: dp[i][j][len] = (dp[i][j][k] && dp[i+k][j+k][len-k] )|| (dp[i+k][j][len-k] && dp[i][j+len-k][k] )
(i为s1的起始,j为s2的起始,长度为len的scramble)
第九十一题 Decode Ways
本题后面的way和前面的way有关,因此用dp
dp[i]=(s[i-1]==0?) 0:dp[i-1]; 值为0时,无法变换,只能靠dp[i-2]的值来判断,下面;
i-1和i-2的数字为10~26:dp[i]+=dp[i-2] dp[i-2] xx 为后面两个值一起翻译的结果 这是一种way dp[i]要加上这种
第九十五题 Unique Binary Search Trees II
*left = DFS(start , i-1) *right = DFS( i+1,end ); push_back(node) node->left , node->right ,node->val
第九十六题 Unique Binary Search Trees
BST:中序遍历为从小到大 卡塔兰数列:dp[0]=1,dp[i]+=dp[j]*dp[i-j-1] (看解释)
第九十七题 Interleaving String
建立一个二维dp[m+1][n+1],dp[0][0] = true; dp[i][0] 与 dp[0][j]赋值,
dp[i][j] = (dp[i-1][j]&&s1[i-1]==s3[i+j-1]) || (dp[i][j-1]&&s2[j-1]==s3[i+j-1])
5.Sort
第五十六题 Merge Intervals
本题中有个Interval 类型,其实就是一个区间(start,end)。本题看到merge就是排序类,将start排序,再将end排序,然后比较starts[i+1] > ends[i] 来放入 res值。
第五十七题 Insert Intervals
本题是一个一个比较,有交集则合并,无交集则加入
第六十题 Permutation Sequence
本题要是用next permutation 解时间太长。具体方法很抽象,见pad解析。
6.Two Pointers
第六十一题 Rotate List
两个快慢指针 fast&&slow 1.k%n 2 if(!fast) return head;
第七十四题 Minimum Window Substring
本题需要用到两个算法,hash+two p。 需要一个count 计算每个字符是否出现,因为有的字符可能会出现多次,就会+1。因此保证了所有字符都会出现,然后用一个滑动窗口,先left++,如果count满足 ,继续;否则right++.
第八十题:Remove Duplicates from sorted Array II
pre+cur
第八十一题:Search in Rotated Sorted Array II
类似Search in Rotated Sorted Array, 当A[mid]<A[right],表示左边升序;反之,表示右边升序;相等可以去掉最右边。
第八十六题:Partition List
本题要注意题意,比3小的值都得放在比3大的值前面。 pre=1(4前面), cur=3(后面2比3小)
7.math
第六十五题 Valid Number
本题太繁琐,题目中没有标明的特殊例子:" -.7e+0435",".e1"," -.","6+1"," ","e",
grandyoung 的方法二作了总结,比较好。
第六十六题:Plus One
新型用法;if(digits.front()==0) digits.insert(digits.begin(),1);
第六十七题 Add Binary
本题需要注意的是 int 到 char类型的转换 ,可以用 to_string, 也可以用 char s= (char)(sum%2 +'0');
第八十九题 Gray Code
采用gray code 镜像的方法,
for(int j= size-1;j>=0;j--) res.push_back(res[j]|(1<<i));
8 binary search
while(left<right) mid=...
第六十九题
signed integer overflow: 46341 * 46341 cannot be represented in type 'int' (solution.cpp)
本题注意会超过int 1.用long 2.if(x/mid>=mid && x/(mid+1)<(mid+1)
第七十四题 Search a 2D Matrix
本题先用bina-search确定哪一行mid,再用left&&right遍历那一行。
9. ListNode
第八十三题:Remove Duplicates from Sorted List
cur=cur->next;
第八十二题:Remove Duplicates from Sorted List II
tp, pre+cur; while() cur=cur->next; pre-next=cur->next;
第九十二题:Reverse Linked List II
该题把list拆成两段,一个一点一点去掉需要反转的链表,一个是反转的链表,再接上。用了一个front指针,front=cur;
10.Depth - first
第九十八题:Validate Binary Search Tree
中序遍历从小到大为BST ,构造子函数 isValidBST1(TreeNode *root, long min,long max)
第九十九题: Recover Binary Search Tree
1.O(n)中序遍历取出值来,进行排序,赋值(注:得用个链表指针指向中序遍历的节点,无法直接赋值的)
2.O(1) 见解释。构造一个可以再次完成中序遍历的指针的数据结构,pre,second,parent。
1)无左支,直接比较右支,看跟和右的大小
2)有左支,先找到该左支的最右点,中序遍历为左根右,因此右完了会指向根的根,若右指向了根的根,则该右支比较晚,根据左根右的原则,比较其右支。
第100题 Same Tree
注意比较节点是不是存在
11.Greedy
第五十五题:Jump Game,与 前五十道中Jump Game II 对应
dp[i]=max(dp[i-1],A[i-1])-1; 上一次剩下的步数和上一次值取最大减一
12.hash
第七十六题:
本题是滑动窗口,用gandyang博客的方法比较快,
if(--m[s[i]]>=0) ++cnt;
cnt==t.size(): res; if(++m[s[left]]>0) --cnt;
13.stack
第九十四题 Binary Tree Inorder Traversal
本题可以用递归,但是太简单,有一种方法是用栈,按照根左保存数据,出来就是左根右了。