Leetcode总结
1.Two Pointers
SUMS 类型:
第十五题:3SUMS:
1.三层重复值跳过,i+left+right;2.排序后当前值大于目标值提前退出
注:也可以用Hash,但是复杂度不会有变化 N^2,还有一个小弊端就是第一层重复值不能跳过
第十六题:3SUMS CLOSEST:
方法基本同上,区别就是要设置初始值方便后面比较
第十八题:4SUM:
方法基本同上,区别就是增加了一重循环,另外重复值只考虑第一层?
第二十六题:Remove Duplicates from Sorted Array
本题要求在原数组空间上remove,因此采取两个指针,一个在前面赋值,另一个在后面找数,A[++pre]=A[cur++]
比较经典。
第十九题. Remove Nth Node From End of the List
本题要求一遍遍历,像这种情况一般需要两个快慢指针,一个先前到达位置,另一个从头开始。
第二十八题:Implement strStr()
本题的意思是判断子字符串在字符串中的位置,需要两个for循环,第一个遍历字符串,第二个指针在两个字符串都游走,配对字符串。
第四十二题: Trapping Rain water
先从左往右扫,找到左边极大值;再从右往左扫,找到右边极大值;取两者min,减去当前值。
第十一题: Container With Most Water
本题要找min(两个棍)*距离 最大值 。
2.HASH
SUMS 类型:
第一题:.Two SUMS: Hash,快速匹配目标值。注:map.count() 元素的个数
第三题:Longest Substring WithoutRepeating Characters
Two Pointers+HASH,用两个指针(left,right)一直保持在非重复区间,区间内数值用hash存储。
注:map.find()!=map.end map.erase()
第十三题:Roman to Integer
HASH表建立{I,1},根据前后值判断:res+=val;res-=val;
第三十题:Substing with concatation of All words
需要构建两个HASH表,第一个存words及其数量,第二个存s上剪下来(SUBSTR)的words及其数量,如果数量超了,则退出;长度达到words,放入res。
第三十六题:Valid Sudoku
判断一个数组是不是数独,行列小方格不能有重复元素即可(肯定有解)。另外注意小方格三重循环:k:0·9;i:k/3*3-k/3*3+3; j:k%3-k%3*3+3;Valid Sudoku leetcode java - 爱做饭的小莹子 - 博客园 (用map替代里面的set)
第四十九题:Group Anagrams
HASH,map<string,vector<string>>m;
3.Binary Search:复杂度log(m+n)
第四题: Median of Two Sorted Arrays,
求两个排序合并后的第K值,即是删除前k-1数的留下的第一个值。二分法是按照例如k/2删数,直到删到目标个数为止。注:一个序列为空,返回第二个序列的k-a值,a为已删个数;k==1 k/2==0 不能继续删,直接返回两个序列中最小的第一个
第三十三题:Search in Rotated Sorted Array
本题里的序列有未知旋转,可知右边一直为升序,因此根据最右面数和中间数判断在右半部还是左半部分,left=mid+1或right=mid-1.
第三十四题:Search for a Range
本题要求log(n)复杂度,用二分法。找到值所在的位置,然后left--,right++ 找到两边值。
第三十五题:Search Insert Position
本题开头判断是0还是n-1, 注意的一点是 right=mid,因为mid-1可能比target小。
4.动态规划 DP :
第五题 : Longest Palindromic Substring
注意找到DP的关系式:dp[j][i]=(s[i]==s[j]&&(i-j<2||dp[j+1][i-1]))
第十题:Regular Expression Matching
‘*’代表之前字符出现的次数,dp[i][j] = dp[i][j-2] 代表之前数出现0次;dp[i][j] = dp[i-1][j]&&...代表出现至少一次。
第三十二题: Longest Valid Parenthese
寻找最长匹配子串,有两种解法,第一种是用栈,注意要push坐标点和设置start点,栈为空的时候设置start点,不为空的时候计算res=i-m.top()
第二种解法dp,省时间。
第四十四题:Widcard Matching
"*":dp[i]=dp[i-1][j]||dp[i][j-1]; 当前状态跟上一个状态有关
第十题:Regular Expression Matching
本题要注意根上一个区别,*只能替换preseding的任意字符。
5.Backtrack (DFS):
第二十二题:Generate Parentheses
本题相当于遍历left,right,左-〉右,如下所示,注意限制条件,右的个数不能比左大
n=3 例子:
[
"((()))", left->left->left->right->right->right
"(()())", left->left->right->left->right->right
"(())()", left->left->right->right->left->right
"()(())", left->right->left->left->right->right
"()()()" left->right->left->right->left->right
]
第十七题.Letter Combinations of a Phone Number
此问题用递归+DFS。若用for循环遍历,每次找到都得从头开始找 ,回溯节省了共同子序列的时间。
第三十七题:SudoKu Solver
此问题对当前值(i,j)遍历0-9,看是否valid,然后DFS下一个元素。
第三十九题:Combination Sum
此问题允许重复使用数字,先sort数组,DFS遍历所有数字达到target退出。
第四十题 :Combination Sum II
为上一道题的延伸,但是不允许重复数字,先找到不重复的位置i,DFS的时候输入参数i+1
第四十六题:Permutations
递归+DFS
第四十七题:Permutations
先排序,重复的跳过;
6.stack:
第三十二题: Longest Valid Parenthese
寻找最长匹配子串,有两种解法,第一种是用栈,注意要push坐标点和设置start点,栈为空的时候设置start点,不为空的时候计算res=i-m.top()
第二十题.Valid Parentheses
本题是符号配对,这种情况应该第一想到栈,push '(', if ')',top=='('? pop'('
7.Math类型:
第七题:
比如INT_MAX=2147483647,翻转后就溢出了,所以 不能直接翻转。
1.用longlong型;2.判断abs(res) >INT_MAX/10;
第九题:Palindrome Number
要求不能用额外空间&&直接翻转可能会overflow
取两头数值进行比较,例如123,取1和3进行比较
第二十九题:Divide Two Intergers
本题都用long long?,用2为基地算。注意边界条件:1,被除数为0,2INT_MIN,INT_MAX,
第四十三题:Mutiply Strings
1)每个位置相乘,存数字;2)进位计算 carry 3)输出,数字变为字符
第五十题:pow(x,n)
i/=2: x*=x; if(i%2!=0) res*=x;
第十二题:Integer to Roman
构造两个表,存 {1000,900....}和对应的罗马值{"M","CM"...}
8.ListNode类型:
第二题:Add Two Numbers
本题需要考虑进位,设置一个单独的进位变量;另外把l1和l2更长的再加上就行了
第二十一题:Merge Two Sorted Lists
初始化头,再遍历比较,小的放在当前;较长的那个list剩下的直接放在最后。
第二十三题:Merge K Sorted Lists
用了上一题的两个list来merge作为子函数,然后在此基础上完成所有merge,类似于归并排序
第二十四题.Swap Nodes in Paris
本题要求不改变值,只改变nodes,另外注意保存后面的指针,防止链表断开(本题第三遍刷的时候用代码跑一遍)
第二十五题.Reverse Nodes in K-Group
子函数reverse(ListNode),主函数循环
9.Array类型:
第二十七题,Remove Element
if(nums[i]!=valuse) nums[res++] = nums[i]
第三十一题,Next Permutation
本题的意思是全排列的下一个排列组合,需要两个for循环,(自己举例子看)
1,从后往前找num[i+1]>num[i];
2 , 从后到i找比num[i]大的值,进行swap
3.最后reverse(i+,end);
第四十一题:First Missing Positive
1.要求O(n)时间,O(1)空间,因此不能用排序算法,且最好在原数组做。
2.思想:i位置放i-1的数字,swap(nums[i],nums[nums[i]-1)多次进行排序
(i>0&&i<n,因为默认是连续数字,缺少的数字不会超过n),最后输出缺少的数字即可。
第四十八题:Rotate Image
方法一:[i][j]=>[n-1-j][i]=>[n-1-i][n-1-j]=>[j][n-1-i] i:(0-n/2) j:(i:n-1-i)(为了避免重复)??
方法二:先对角折,再上下翻
10.Greedy
第四十五题:Jump Game II
while(cur<n-1) :大了就能到头了;while(i<=pre):每个i都会遍历,从而找到最大跨度。
第五十五题:Jump Game
maxidx=max(manIdx,i+A[I];
11.string
第六题: ZigZag Conversion
第一行和最后一行相差2*nRow-2,其他的行隔一个相差2*nRow-2,相邻的相差size-2*row;
第八题:String to Integer
注意题目说的几个边界条件。1.正负数;2开头空格;3.空序列 4.INT_MAX 2147483647 最后一位不能大于7
第十四题:Longest Common Prefix
取第一个字符串的字符c,在后面的字符串中找。
第三十八题:Count and Say
后一个是上一个的数字统计,多重循环即可。