/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode*sortList(ListNode* head){int n =0;for(ListNode *p = head; p; p = p->next) n ++;
ListNode *dummy = new ListNode(-1);
dummy->next = head;for(int i =1; i < n; i *=2){
ListNode *begin = dummy;for(int j =0; j + i < n; j += i *2){
ListNode *first = begin->next,*second = first;for(int k =0; k < i; k ++)
second = second->next;int f =0, s =0;while(f < i && s < i && second)if(first->val < second->val){
begin = begin->next = first;
first = first->next;
f ++;}else{
begin = begin->next = second;
second = second->next;
s ++;}while(f < i){
begin = begin->next = first;
first = first->next;
f ++;}while(s < i && second){
begin = begin->next = second;
second = second->next;
s ++;}
begin->next = second;}}return dummy->next;}};
LeetCode 17. Letter Combinations of a Phone Number
class Solution {
public:// state = {""}// for 每个数字// for c = 当前数字的所有备选字母// for s = state中的所有字符串// s += c
string chars[8]={"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
vector<string>letterCombinations(string digits){if(digits.empty())return vector<string>();
vector<string>state(1,"");for(auto u : digits){
vector<string> now;for(auto c : chars[u -'2'])for(auto s : state)
now.push_back(s + c);
state = now;}return state;}};
LeetCode 46. Permutations
class Solution {
public:int n;//用来标记某个数字是否用了
vector<bool> st;//存储最终的答案
vector<vector<int>> ans;//存储当前的答案
vector<int> path;
vector<vector<int>>permute(vector<int>& nums){//初始化
n = nums.size();
st = vector<bool>(n);//深搜+回溯dfs(nums,0);return ans;}voiddfs(vector<int>& nums,int u){//达到了终止条件if(u == n){
ans.push_back(path);return;}for(int i =0; i < n; i++){if(!st[i]){//标记现场
st[i]= true;
path.push_back(nums[i]);dfs(nums, u +1);//恢复现场
path.pop_back();
st[i]= false;}}}};
LeetCode 47. Permutations II
class Solution {
public://这里用全局,值引用,这样就不用重复赋值int n;//答案
vector<vector<int>> ans;//当前枚举的路径
vector<int> path;//标记数组
vector<bool> st;
vector<vector<int>>permuteUnique(vector<int>& nums){//初始化
n = nums.size();
st = vector<bool>(n);
path = vector<int>(n);//这里通过排序,使得相同的数字排在一块了,对于相同的数字人为规定一个顺序sort(nums.begin(), nums.end());dfs(nums,0,0);return ans;}voiddfs(vector<int>& nums,int u,int start){//终止条件if(u == n){
ans.push_back(path);return;}//是否是相同的数字,如果是则接着找for(int i = start; i < n; i++){if(!st[i]){
st[i]= true;
path[i]= nums[u];dfs(nums, u +1, u +1< n && nums[u+1]== nums[u]? i :0);
st[i]= false;}}}};
LeetCode 78. Subsets
class Solution {
public:
vector<vector<int>>subsets(vector<int>& nums){//这里存答案
vector<vector<int>> res;//每个数字有两种状态,所以一共有1 << nums.size()中状态,然后填充答案即可for(int i =0; i <1<< nums.size(); i++){
vector<int> now;for(int j =0; j < nums.size(); j++){if(i >> j &1)
now.push_back(nums[j]);}
res.push_back(now);}return res;}};
LeetCode 90. Subsets II
class Solution {
public://常规操作,变量
vector<vector<int>> ans;
vector<int> path;
vector<vector<int>>subsetsWithDup(vector<int>& nums){//排个序,这样相同的数字会排在一块sort(nums.begin(), nums.end());dfs(nums,0);return ans;}voiddfs(vector<int>& nums,int u){//终止条件if(u == nums.size()){
ans.push_back(path);return;}//这里不一样了,有多少个重复的数字int k =0;while(u + k < nums.size()&& nums[u + k]== nums[u])k++;for(int i =0; i <= k; i ++){dfs(nums, u + k);
path.push_back(nums[u]);}for(int i =0; i <= k; i++)path.pop_back();}};
LeetCode 39. Combination Sum
class Solution {
public:
vector<vector<int>>combinationSum(vector<int>& candidates,int target){
vector<vector<int>> res;
vector<int> vec;dfs(candidates,0,0, target, vec, res);return res;}voiddfs(vector<int>& candidates,int cur,int n,int target, vector<int>&vec, vector<vector<int>>&res){if(cur >= target){if(cur == target)
res.push_back(vec);return;}for(int i = n; i < candidates.size(); i++){
vec.push_back(candidates[i]);dfs(candidates, cur+candidates[i], i, target, vec, res);
vec.pop_back();}}};
LeetCode 40. Combination Sum II
class Solution {
public:
vector<vector<int>> ans;
vector<int> path;voiddfs(vector<int>&a,int sum,int start){if(sum <0)return;if(sum ==0) ans.push_back(path);for(int i = start; i < a.size(); i++){if(i > start && a[i]== a[i -1])continue;
path.push_back(a[i]);dfs(a, sum - a[i], i+1);
path.pop_back();}}
vector<vector<int>>combinationSum2(vector<int>& candidates,int target){sort(candidates.begin(), candidates.end());dfs(candidates, target,0);return ans;}};
LeetCode 216. Combination Sum III
class Solution {
public:
vector<vector<int>> ans;
vector<int> path;
vector<vector<int>>combinationSum3(int k,int n){dfs(k,1, n);return ans;}voiddfs(int k,int start,int n){if(!k){if(!n) ans.push_back(path);return;}for(int i = start; i <=10- k; i++){
path.push_back(i);dfs(k -1, i +1, n - i);
path.pop_back();}}};
LeetCode 22. Generate Parentheses
class Solution {
public:
vector<string> res;voidsolve(int l,int r,int n, string cur){if(l == n && r == n){
res.push_back(cur);return;}if(l < n)solve(l +1, r, n, cur +"(");if(r < l)solve(l, r +1, n, cur +")");}
vector<string>generateParenthesis(int n){if(n ==0)return res;solve(0,0, n,"");return res;}};
LeetCode 473. Matchsticks to Square
class Solution {
public:// 这题是裁剪的经典题目:// 首先是依次构造正方的每条边// 剪枝:// 1.从大到小枚举所有边// 2.每条边内部的木棒长度规定成从大到小// 3.如果当前木棒拼接失败,则跳过接下来所有长度相同的木棒// 4.如果当前木棒拼接失败,且是当前边的第一个,则直接剪掉当前分支// 5.如果当前木棒拼接失败,且是当前边的最后一个,则直接剪掉当前分支
vector<bool> st;
bool makesquare(vector<int>& nums){int sum =0;for(auto u : nums) sum += u;if(!sum || sum %4)return false;sort(nums.begin(), nums.end());reverse(nums.begin(), nums.end());
st = vector<bool>(nums.size());returndfs(nums,0,0, sum /4);}
bool dfs(vector<int>& nums,int u,int cur,int length){if(cur == length)u++, cur =0;if(u ==4)return true;for(int i =0; i < nums.size(); i++){if(!st[i]&& cur + nums[i]<= length){
st[i]= true;if(dfs(nums, u, cur + nums[i], length))return true;
st[i]= false;if(!cur)return false;if(cur + nums[i]== length)return false;while(i +1< nums.size()&& nums[i]== nums[i+1]) i++;}}return false;}};
LeetCode 52. N-Queens II
class Solution {
public:int ans;
vector<bool> row, col, diag, anti_diag;inttotalNQueens(int n){
row = col = vector<bool>(n, false);
diag = anti_diag = vector<bool>(2* n, false);
ans =0;dfs(0,0,0, n);return ans;}voiddfs(int x,int y,int s,int n){if(y == n) x ++, y =0;if(x == n){if(s == n)++ ans;return;}dfs(x, y +1, s, n);if(!row[x]&&!col[y]&&!diag[x + y]&&!anti_diag[n -1- x + y]){
row[x]= col[y]= diag[x + y]= anti_diag[n -1- x + y]= true;dfs(x, y +1, s +1, n);
row[x]= col[y]= diag[x + y]= anti_diag[n -1- x + y]= false;}}};
LeetCode 37. Sudoku Solver
class Solution {
public://不明觉厉
bool row[9][9]={0}, col[9][9]={0}, cell[3][3][9]={0};voidsolveSudoku(vector<vector<char>>& board){for(int i =0; i <9; i++){for(int j =0; j <9; j++){char c = board[i][j];if(c !='.'){int t = c -'1';
row[i][t]= col[j][t]= cell[i /3][j /3][t]= true;}}}dfs(board,0,0);}
bool dfs(vector<vector<char>>& board,int x,int y){if(y ==9) x++, y =0;if(x ==9)return true;if(board[x][y]!='.')returndfs(board, x, y+1);for(int i =0; i <9; i++){if(!row[x][i]&&!col[y][i]&&!cell[x /3][y /3][i]){
board[x][y]='1'+ i;
row[x][i]= col[y][i]= cell[x /3][y /3][i]= true;if(dfs(board, x, y +1))return true;
row[x][i]= col[y][i]= cell[x /3][y /3][i]= false;
board[x][y]='.';}}return false;}};
LeetCode 282. Expression Add Operators
class Solution {
public:
vector<string> res;
string exp;int n;
vector<string>addOperators(string num,int target){
n = num.length();
exp =string(n *2,' ');dfs(num, target,0,0,0,0);return res;}voiddfs(string &num,int target,int pos,int len,long prev,long cur){if(pos == n){if(cur == target) res.push_back(exp.substr(0, len));return;}longlong next =0;int s = pos, l = len;if(s !=0)++len;while(pos < n){
next = next *10+(num[pos]-'0');if(num[s]=='0'&& pos - s >0)break;if(next > INT_MAX)break;
exp[len++]= num[pos++];if(s ==0){dfs(num, target, pos, len, next, next);continue;}
exp[l]='+';dfs(num, target, pos, len, next, cur + next);
exp[l]='-';dfs(num, target, pos, len,-next, cur - next);
exp[l]='*';dfs(num, target, pos, len, prev*next, cur - prev + prev * next);}}};
LeetCode 301. Remove Invalid Parentheses
class Solution {
public://搜索+剪枝
vector<string> res;
vector<string>removeInvalidParentheses(string s){int l =0, r =0, n = s.length();for(int i =0; i < n; i++){if(s[i]=='(') l++;if(l ==0&& s[i]==')') r++;elseif(s[i]==')') l--;}dfs(s,0, l, r);return res;}
bool check(string s){int cnt =0, n = s.length();for(int i =0; i < n; i++){if(s[i]=='(') cnt++;elseif(s[i]==')') cnt--;if(cnt <0)return false;}return cnt ==0;}voiddfs(string s,int u,int l,int r){if(l ==0&& r ==0){if(check(s)) res.push_back(s);return;}int n = s.length();for(int i = u; i < n; i++){if(s[i]!='('&& s[i]!=')')continue;if(i == u || s[i]!= s[i -1]){
string cur = s;
cur.erase(i,1);if(s[i]=='('&& l >0)dfs(cur, i, l -1, r);elseif(s[i]==')'&& r >0)dfs(cur, i, l, r -1);}}}};
树专题
LeetCode 101. Symmetric Tree
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*///方法一// 1.两个根节点的值要想相等// 2.左边的左子树和右边的右子树对称// 3.左边的右子树和右边的左子树对称// class Solution {// public:// bool isSymmetric(TreeNode* root) {// if(!root) return true;// return dfs(root->left, root->right);// }// bool dfs(TreeNode* p, TreeNode* q)// {// if(!p || !q) return !p && !q;// return p->val == q->val && dfs(p->left, q->right) && dfs(p->right, q->left);// }// };//方法二//左边:左中右遍历,右边:右中左进行遍历//这种方法就是用迭代的方式进行的
class Solution {
public:
bool isSymmetric(TreeNode* root){if(!root)return true;
stack<TreeNode*>left, right;auto l = root->left, r = root->right;while(l || r || left.size()|| right.size()){while(l && r){
left.push(l), l = l->left;
right.push(r), r = r->right;}if(l || r)return false;
l = left.top(), left.pop();
r = right.top(), right.pop();if(l->val != r->val)return false;
l = l->right, r = r->left;}return true;}};
LeetCode 104. Maximum Depth of Binary Tree
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:intmaxDepth(TreeNode* root){return root ?max(maxDepth(root->left),maxDepth(root->right))+1:0;}};
LeetCode 145. Binary Tree Postorder Traversal
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int>postorderTraversal(TreeNode* root){
vector<int> result, left, right;if(!root)return result;
left =postorderTraversal(root->left);for(auto&x:left) result.push_back(x);
right =postorderTraversal(root->right);for(auto&x:right) result.push_back(x);
result.push_back(root->val);return result;}};
LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
unordered_map<int,int> pos;
TreeNode*buildTree(vector<int>& preorder, vector<int>& inorder){int n = preorder.size();for(int i =0; i < n; i++)pos[inorder[i]]= i;returndfs(preorder, inorder,0, n-1,0, n-1);}
TreeNode*dfs(vector<int>& preorder, vector<int>& inorder,int pl,int pr,int il,int ir){if(pl > pr)returnNULL;int val = preorder[pl];int k = pos[val];int len = k - il;auto root = new TreeNode(val);
root->left =dfs(preorder, inorder, pl +1, pl + len, il, k-1);
root->right =dfs(preorder, inorder, pl + len +1, pr, k+1, il);return root;}};
LeetCode 331. Verify Preorder Serialization of a Binary Tree
class Solution {
public:
bool ans = true;
bool isValidSerialization(string preorder){
preorder +=',';int u =0;dfs(preorder, u);return ans && u == preorder.size();}voiddfs(string &preorder,int&u){if(u == preorder.size()){
ans = false;return;}if(preorder[u]=='#'){
u +=2;return;}while(preorder[u]!=',') u ++; u ++;dfs(preorder, u);dfs(preorder, u);}};
LeetCode 102. Binary Tree Level Order Traversal
if(!root)return res;//使用队列进行bfs,也可以用数组去实现
queue<TreeNode*> q;
q.push(root);while(q.size()){//队列的长度就是需要输出的长度int len = q.size();
vector<int> level;//一方面需要把数值加到队列中,一方面不要忘记了扩展队列for(int i =0; i < len; i++){auto t = q.front();
q.pop();
level.push_back(t->val);if(t->left) q.push(t->left);if(t->right) q.push(t->right);}
res.push_back(level);}return res;
LeetCode 653. Two Sum IV - Input is a BST
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> inorder;
bool findTarget(TreeNode* root,int k){dfs(root);for(int i =0, j = inorder.size()-1; i < j; i++){while(i < j && inorder[i]+ inorder[j]> k) j--;if(i < j && inorder[i]+ inorder[j]== k)return true;}return false;}voiddfs(TreeNode *root){if(!root)return;dfs(root->left);
inorder.push_back(root->val);dfs(root->right);}};
LeetCode 236. Lowest Common Ancestor of a Binary Tree
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*///这题不是很明白//如果以root为根的子树中包含p和q,则返回他们最近的公共祖先//如果只包含p,则返回p//如果只包含q,则返回q//如果都不包含,则返回NULL
class Solution {
public:
TreeNode*lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q){if(!root || root == p || root == q)return root;auto left =lowestCommonAncestor(root->left, p, q);auto right =lowestCommonAncestor(root->right, p, q);if(!left)return right;if(!right)return left;return root;}};
LeetCode 543. Diameter of Binary Tree
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*///枚举所有的最高点//递归时需要计算,从当前结点往下走,深层的最大值
class Solution {
public:int ans =0;intdiameterOfBinaryTree(TreeNode* root){dfs(root);return ans;}intdfs(TreeNode *root){if(!root)return0;auto left =dfs(root->left);auto right =dfs(root->right);
ans =max(ans, left + right);returnmax(left+1, right+1);}};
LeetCode 124. Binary Tree Maximum Path Sum
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*///这题和求树的最大直径是很相似的,dfs返回的不是答案,而是深度
class Solution {
public:int ans = INT_MIN;intmaxPathSum(TreeNode* root){dfs(root);return ans;}intdfs(TreeNode *root){if(!root)return0;auto left =dfs(root->left);auto right =dfs(root->right);
ans =max(ans, left + root->val + right);returnmax(0, root->val +max(left, right));}};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:voidrecoverTree(TreeNode* root){
TreeNode* first =NULL,*second,*prep =NULL;while(root){if(!root->left){if(prep && prep->val > root->val){if(!first) first = prep, second = root;else second = root;}
prep = root;
root = root->right;}else{
TreeNode *p = root->left;while(p->right && p->right != root) p = p->right;if(!p->right){
p->right = root;
root = root->left;}else{
p->right =NULL;if(prep && prep->val > root->val){if(!first) first = prep, second = root;else second = root;}
prep = root;
root = root->right;}}}swap(first->val, second->val);}};
LeetCode 337. House Robber III
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
unordered_map<TreeNode*, unordered_map<int,int>>f;introb(TreeNode* root){dfs(root);returnmax(f[root][0], f[root][1]);}voiddfs(TreeNode *root){if(!root)return;dfs(root->left);dfs(root->right);
f[root][1]= root->val + f[root->left][0]+ f[root->right][0];
f[root][0]=max(f[root->left][0], f[root->left][1])+max(f[root->right][0], f[root->right][1]);}};
动态规划专题(1/2)
LeetCode 53. Maximum Subarray
class Solution {
public://求出所有子段的和的最大值//枚举所有的起点和终点intmaxSubArray(vector<int>& nums){int res = INT_MIN, last =0;for(int i =0; i < nums.size(); i++){int now =max(last,0)+ nums[i];
res =max(res, now);
last = now;}return res;}};
LeetCode 300. Longest Increasing Subsequence
class Solution {
public:intlengthOfLIS(vector<int>& nums){int n = nums.size();
vector<int>f(n);for(int i =0; i < n; i++){
f[i]=1;for(int j =0; j < i; j++)if(nums[j]< nums[i])
f[i]=max(f[i], f[j]+1);}int res =0;for(int i =0; i < n; i++) res =max(res, f[i]);return res;}};
LeetCode 72. Edit Distance
class Solution {
public:intminDistance(string word1, string word2){int n = word1.size(), m = word2.size();
vector<vector<int>>f(n +1, vector<int>(m +1));for(int i =0; i <= n; i++) f[i][0]= i;for(int i =0; i <= m; i++) f[0][i]= i;for(int i =1; i <= n; i++)for(int j =1; j <= m; j++){
f[i][j]=min(f[i -1][j], f[i][j -1])+1;
f[i][j]=min(f[i][j], f[i -1][j -1]+(word1[i -1]!= word2[j -1]));}return f[n][m];}};
LeetCode 121. Best Time to Buy and Sell Stock
class Solution {
public:intmaxProfit(vector<int>& prices){if(prices.size()<2)return0;int profit =0, low = prices[0];for(int i =1; i < prices.size(); i++){
profit =max(profit, prices[i]- low);
low =min(low, prices[i]);}return profit;}};
LeetCode 122. Best Time to Buy and Sell Stock II
class Solution {
public:intmaxProfit(vector<int>& prices){int sum =0;//遍历一次数组,低进高出,把正的价格相加就是最终的利润for(int i =1; i < prices.size(); i++)if(prices[i]> prices[i-1])
sum += prices[i]- prices[i-1];return sum;}};
LeetCode 123. Best Time to Buy and Sell Stock III
class Solution {
public:intmaxProfit(vector<int>& prices){int n = prices.size();if(!n)return0;
vector<int>f(n,0);int minv = INT_MAX;// 从前往后扫描for(int i =0; i < n; i++){if(i) f[i]= f[i -1];if(prices[i]> minv)
f[i]=max(f[i], prices[i]- minv);
minv =min(minv, prices[i]);}int res = f[n -1];int maxv = INT_MIN;// 从后往前扫描for(int i = n -1; i >0; i--){if(prices[i]< maxv)
res =max(res, maxv - prices[i]+ f[i -1]);
maxv =max(maxv, prices[i]);}return res;}};
LeetCode 188. Best Time to Buy and Sell Stock IV
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
int n = prices.size();
if( k >= n / 2)
{
int res = 0;
for(int i = 1; i < n; i++)res += max(0, prices[i] - prices[i - 1]);
return res;
}
int f[k + 1], g[k + 1];
for(int i = 0; i <= k; i++) f[i] = 0, g[i] = INT_MIN;
for(int cur : prices)
for(int i = k; i; i--)
{
f[i] = max(f[i], g[i] + cur);
g[i] = max(g[i], f[i - 1] - cur);
}
return f[k];
}
};
LeetCode 309. Best Time to Buy and Sell Stock with Cooldown
class Solution {
public:intmaxProfit(vector<int>& prices){int n = prices.size();int f =0;int g =-1000000000;int h =-1000000000;for(int i =0; i < n; i++){int new_f =max(f,g);int new_g = h + prices[i];int new_h =max(h, f - prices[i]);
f = new_f;
g = new_g;
h = new_h;}returnmax(f,g);}};
LeetCode 198. House Robber
class Solution {
public:introb(vector<int>& nums){int n = nums.size();
vector<int>f(n+1),g(n+1);for(int i =1; i <= n; i++){
f[i]=max(f[i -1], g[i -1]);
g[i]= f[i -1]+ nums[i -1];}returnmax(f[n], g[n]);}};
LeetCode 213. House Robber II
class Solution {
public:introb(vector<int>& nums){int n = nums.size();if(n ==0)return0;if(n ==1)return nums[0];if(n ==2)returnmax(nums[0], nums[1]);int ans =0, f, g;//选择第一个
f = nums[2], g =0;for(int i =3; i < n; i++){int last_f = f, last_g = g;
f = last_g + nums[i];
g =max(last_f, last_g);}
ans = g + nums[0];//不选择第一个
f = nums[1], g =0;for(int i =2; i < n; i++){int last_f = f, last_g = g;
f = last_g + nums[i];
g =max(last_f, last_g);}
ans =max(ans,max(f,g));return ans;}};
LeetCode 312. Burst Balloons
class Solution {
public:intmaxCoins(vector<int>& nums){int n = nums.size();//在num最前面插入一个1
nums.insert(nums.begin(),1);//在num最后面插入一个1
nums.push_back(1);
vector<vector<int>>dp(n+2, vector<int>(n+2,0));for(int len =1; len <= n; len++)for(int i =1; i <= n - len +1; i++){int j = i + len -1;for(int k = i; k <= j; k++){
dp[i][j]=max(dp[i][j], dp[i][k -1]+ nums[i -1]*nums[k]*nums[j+1]+ dp[k+1][j]);}}return dp[1][n];}};
LeetCode 96. Unique Binary Search Trees
class Solution {
public:intnumTrees(int n){
vector<int>f(n+1);
f[0]=1;//f[n]表示n个节点的二叉搜索树共有多少种for(int i =1; i <= n; i++){
f[i]=0;for(int j =1; j <= i; j++)
f[i]+= f[j -1]* f[i - j];}return f[n];}};
LeetCode 140. Word Break II
class Solution {
public:
vector<string> ans;
unordered_map<string,int> dict;
vector<string>wordBreak(string s, vector<string>& wordDict){for(auto&word : wordDict) dict[word]=1;int n = s.size();
vector<bool>f(n+1, true);for(int i =1; i <= n; i++){
f[i]= false;for(int j =0; j < i; j++)if(dict[s.substr(j, i - j)]&& f[j]){
f[i]= true;break;}}dfs(f, s,"", n);return ans;}voiddfs(vector<bool>&f, string &s, string path,int u){if(!u){
ans.push_back(path.substr(0, path.size()-1));return;}for(int i =0; i < u; i++)if(dict[s.substr(i, u - i)]&& f[i])dfs(f, s, s.substr(i, u - i)+' '+ path, i);}};
LeetCode 10. Regular Expression Matching
class Solution {
public:
bool isMatch(string s, string p){int n = s.size(), m = p.size();
s =' '+ s, p =' '+ p;
vector<vector<bool>>f(n +1, vector<bool>(m +1));for(int i =0; i <= n; i++)for(int j =0; j <= m; j++)if(!i &&!j) f[i][j]= true;else{if(j +1<= m && p[j +1]=='*')continue;if(p[j]!='*'){if(p[j]=='.'|| s[i]== p[j])if(i >0&& j >0)
f[i][j]= f[i -1][j -1];}else{if(j >=2) f[i][j]= f[i][j -2];if(i >0& j >0){if(p[j -1]=='.'|| s[i]== p[j -1])if(f[i -1][j])
f[i][j]= true;}}}return f[n][m];}};
字符串专题
LeetCode 38. Count and Say
class Solution {
public://模拟题
string countAndSay(int n){
string s ="1";for(int i =0; i < n-1; i++){
string ns;for(int j =0; j < s.size(); j++){//常用技巧int k = j;while(k < s.size()&& s[k]== s[j])k++;
ns +=to_string(k - j)+ s[j];
j = k -1;}
s = ns;}return s;}};
class Solution {
public:
string reverseWords(string s){//首先翻转每一个单词,然后翻转整个句子就能达到这样的效果int k =0;for(int i =0; i < s.size(); i++){while(i < s.size()&& s[i]==' ')i++;if(i == s.size())break;int j = i;while(j < s.size()&& s[j]!=' ')j++;reverse(s.begin()+ i, s.begin()+ j);if(k) s[k++]=' ';while(i < j)s[k++]= s[i++];}
s.erase(s.begin()+ k, s.end());reverse(s.begin(), s.end());return s;}};
LeetCode 165. Compare Version Numbers
class Solution {
public:intcompareVersion(string s1, string s2){//这里使用双指针进行比较int i =0, j =0;while(i < s1.size()|| j < s2.size()){int x = i, y = j;//x, y分别代表每一段的值,这里用到了常用的编码方式,移动指针while(x < s1.size()&& s1[x]!='.') x++;while(y < s2.size()&& s2[y]!='.') y++;//将字符转化为数字int a = i == x ?0:atoi(s1.substr(i, x - i).c_str());int b = j == y ?0:atoi(s2.substr(j, y - j).c_str());if(a > b)return1;if(a < b)return-1;//移动到下一段
i = x +1, j = y +1;}return0;}};
LeetCode 5. Longest Palindromic Substring
class Solution {
public:
string longestPalindrome(string s){
string res;//枚举每一个起点,然后向两边扩展for(int i =0; i < s.size(); i++){//奇数的情况for(int j = i, k = i; j >=0&& k < s.size()&& s[j]== s[k]; j--, k++)if(res.size()< k - j +1)
res = s.substr(j, k - j +1);//偶数的情况for(int j = i, k = i +1; j >=0&& k < s.size()&& s[j]== s[k]; j--, k++)if(res.size()< k - j +1)
res = s.substr(j, k - j +1);}return res;}};
LeetCode 273. Integer to English Words
class Solution {
public:
string small[20]={"Zero","One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Eleven","Twelve","Thirteen","Fourteen","Fifteen","Sixteen","Seventeen","Eighteen","Nineteen"};
string decade[10]={"","","Twenty","Thirty","Forty","Fifty","Sixty","Seventy","Eighty","Ninety"};
string big[4]={"Billion","Million","Thousand",""};//这里把每一个分成一段一段的,3个一组
string numberToWords(int num){//特判为0if(!num)return small[0];
string res;for(int i =1000000000, j =0; i >0; i /=1000, j++){if(num >= i){
res +=get_part(num / i)+ big[j]+' ';
num %= i;}}while(res.back()==' ') res.pop_back();return res;}
string get_part(int num){
string res;if(num >=100){
res += small[num /100]+" Hundred ";
num %=100;}if(!num)return res;if(num >=20){
res += decade[num /10]+' ';
num %=10;}if(!num)return res;
res += small[num]+' ';return res;}};
LeetCode 6. ZigZag Conversion
class Solution {
public:
string convert(string s,int n){//模拟题if(n ==1)return s;
string res;for(int i =0; i < n; i++){if(!i || i == n -1){for(int j = i; j < s.size(); j +=2*(n -1)) res += s[j];}else{for(int j = i, k =2*(n -1)- i; j < s.size()|| k < s.size(); j +=2*(n -1), k +=2*(n -1)){if(j < s.size()) res += s[j];if(k < s.size()) res += s[k];}}}return res;}};
LeetCode 3. Longest Substring Without Repeating Characters
class Solution {
public:intlengthOfLongestSubstring(string s){//首先可以想到用hash来判断是不是重复数字//之后先暴力枚举,发现双指针能优化
unordered_map<char,int> hash;int res =0;for(int i =0, j =0; i < s.size(); i++){
hash[s[i]]++;while(hash[s[i]]>1)hash[s[j++]]--;
res =max(res, i - j +1);}return res;}};
LeetCode 166. Fraction to Recurring Decimal
class Solution {
public:
string fractionToDecimal(int _n,int _d){//模拟题,高进度除法longlong n = _n, d = _d;//默认是正数
bool minus = false;//判断除数和被除数是否是负数,如果是则转化为正数运算if(n <0) minus =!minus, n =-n;if(d <0) minus =!minus, d =-d;//首先计算出分数的正数部分
string res =to_string(n / d);
n %= d;//这里集中于小数部分//边界条件,小数为0if(!n){if(minus && res !="0")return'-'+ res;return res;}
res +='.';//这里用哈希表存储所有余数对应的商在小数的第几位
unordered_map<longlong,int> hash;while(n){//如果上一次余数与当前相同,则是循环节,加入跳出循环节if(hash[n]){
res = res.substr(0, hash[n])+'('+ res.substr(hash[n])+')';break;}else{
hash[n]= res.size();}//求小数部分
n *=10;
res +=to_string(n /d);
n %= d;}//加入符号if(minus) res ='-'+ res;return res;}};
LeetCode 208. Implement Trie (Prefix Tree)
class Trie {
public://Trie对应每一个节点的结构体struct Node
{
bool is_end;
Node *son[26];Node(){
is_end = false;for(int i =0; i <26; i++) son[i]=NULL;}}*root;/** Initialize your data structure here. */Trie(){
root = new Node();}//如果为空,则插入,到了结尾处则标记为true/** Inserts a word into the trie. */voidinsert(string word){auto p = root;for(auto c : word){int u = c -'a';if(p->son[u]==NULL)p->son[u]= new Node();
p = p->son[u];}
p->is_end = true;}//查找有没有,中间没有直接return,之后看看结尾标记了/** Returns if the word is in the trie. */
bool search(string word){auto p = root;for(auto c : word){int u = c -'a';if(p->son[u]==NULL)return false;
p = p->son[u];}return p->is_end;}//这个是只要存在就好,不是结尾也是ok的/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(string prefix){auto p = root;for(auto c : prefix){int u = c -'a';if(p->son[u]==NULL)return false;
p = p->son[u];}return true;}};/**
* Your Trie object will be instantiated and called as such:
* Trie* obj = new Trie();
* obj->insert(word);
* bool param_2 = obj->search(word);
* bool param_3 = obj->startsWith(prefix);
*/
LeetCode 131. Palindrome Partitioning
class Solution {
public:
vector<vector<string>> ans;
vector<string> path;
vector<vector<string>>partition(string s){dfs("",0, s);return ans;}//判断当前是否是回文串
bool check(string &now){//直接使用双指针进行判断if(now.empty())return false;for(int i =0, j = now.size()-1; i < j; i++, j--){if(now[i]!= now[j])return false;}return true;}voiddfs(string now,int u, string &s){//遍历完成,递归终止,判断方案,加入if(u == s.size()){if(check(now)){
path.push_back(now);
ans.push_back(path);
path.pop_back();}return;}//在相邻的字符之间放置隔板,可以选择放或者不放if(check(now)){
path.push_back(now);dfs("", u, s);
path.pop_back();}dfs(now + s[u], u +1, s);}};
LeetCode 227. Basic Calculator II
class Solution {
public:intcalculate(string s){//运算符号栈
stack<char> op;//数字栈
stack<int> num;
s +="+0";for(int i =0; i < s.size(); i++){if(s[i]==' ')continue;//符号入符号栈,数字入数字栈if(s[i]=='*'|| s[i]=='/'|| s[i]=='+'|| s[i]=='-') op.push(s[i]);else{//常用遍历方法int j = i;while(j < s.size()&& s[j]>='0'&& s[j]<='9') j++;
num.push(atoi(s.substr(i, j - i).c_str()));
i = j -1;if(!op.empty()){//优先处理乘除,考虑爆栈问题,元素不超过2if(op.top()=='*'|| op.top()=='/'){int y = num.top();
num.pop();int x = num.top();
num.pop();if(op.top()=='*') num.push(x * y);else num.push(x / y);
op.pop();}elseif(op.size()>=2){int z = num.top(); num.pop();int y = num.top(); num.pop();int x = num.top(); num.pop();char op2 = op.top(); op.pop();char op1 = op.top(); op.pop();if(op1 =='+') num.push(x+y), num.push(z);else num.push(x - y), num.push(z);
op.push(op2);}}}}
num.pop();return num.top();}};
LeetCode 30. Substring with Concatenation of All Words
class Solution {
public:intcheck(string s,int begin,int n,int len,int tot, unordered_map<string,int>& wc, vector<int>& ans){
unordered_map<string,int> vis;int count =0;for(int i = begin; i < n - len +1; i += len){
string candidate = s.substr(i, len);if(wc.find(candidate)== wc.end())return i + len;while(vis[candidate]== wc[candidate]){
vis[s.substr(begin, len)]--;
count--;
begin += len;}
vis[candidate]++;
count++;if(count == tot){
ans.push_back(begin);}}return n;}//暴力加枚举,枚举的方式可以按照单词的长度进行枚举
vector<int>findSubstring(string s, vector<string>& words){
vector<int> ans;int n = s.length();int tot = words.size();if(tot ==0)return ans;
unordered_map<string,int> wc;for(int i =0; i < tot; i++)
wc[words[i]]++;int len = words[0].length();for(int offset =0; offset < len; offset++)for(int begin = offset; begin < n; begin =check(s, begin, n, len, tot, wc, ans));return ans;}};
LeetCode 214. Shortest Palindrome
class Solution {
public:
string shortestPalindrome(string s){
string t = s +"#"+string(s.rbegin(), s.rend());int n = t.size();
vector<int>ne(n,0);for(int i =1, j; i < n; i++){
j = ne[i -1];while(j && t[i]!= t[j]) j = ne[j -1];if(t[i]== t[j]) j++;
ne[i]= j;}
string rev = s.substr(ne[n-1]);reverse(rev.begin(), rev.end());return rev + s;/*
string raws = s;
reverse(s.begin(), s.end());
s = raws + '#' + s;
int n = s.size();
vector<int> next(n+1, 0);
for(int i = 2, j = 0; i <= n; i++)
{
while(j && s[j] != s[j - 1]) j = next[j];
if(s[j] == s[i - 1]) j++;
next[i] = j;
}
int res = next[n];
string sup = raws.substr(res);
reverse(sup.begin(), sup.end());
return sup + raws;
*/}};
二分与单调队列/栈专题
LeetCode 69. Sqrt(x)
class Solution {
public:intmySqrt(int x){int l =0, r = x;while(l < r){int mid =(longlong)l + r +1>>1;if(mid <= x/mid)l = mid;else r = mid -1;}return r;}};
LeetCode 34. Find First and Last Position of Element in Sorted Array
class Solution {
public:
vector<int>searchRange(vector<int>& nums,int target){if(nums.empty())return{-1,-1};//找到左边界int l =0, r = nums.size()-1;while(l < r){int mid = l + r >>1;if(nums[mid]>= target)r = mid;else l = mid +1;}if(nums[r]!= target)return{-1,-1};int start = r;//找到右边界
l =0, r = nums.size()-1;while(l < r){int mid = l + r +1>>1;if(nums[mid]<= target)l = mid;else r = mid -1;}int end = r;return{start, end};}};
LeetCode 74. Search a 2D Matrix
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix,int target){//判断边界条件if(matrix.empty()|| matrix[0].empty())return false;//用二分去查找,这里有一个换算关系,最后还要判断是不大于int n = matrix.size(), m = matrix[0].size();int l =0, r = n * m -1;while(l < r){int mid = l + r >>1;if(matrix[mid / m][mid % m]>= target)r = mid;else l = mid +1;}if(matrix[r / m][r % m]!= target)return false;return true;}};
LeetCode 240. Search a 2D Matrix II
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix,int target){if(matrix.empty())return false;int row =0, col = matrix[0].size()-1;//利用规律,从右上角开始找while(row < matrix.size()&& col >=0){int t = matrix[row][col];if(t < target) row++;elseif(t > target) col--;elsereturn true;}return false;}};
LeetCode 153. Find Minimum in Rotated Sorted Array
class Solution {
public:intfindMin(vector<int>& nums){int l =0, r = nums.size()-1;//这里是直接二分,找到分界点while(l < r){int mid = l + r >>1;if(nums[mid]<= nums.back())r = mid;else l = mid +1;}return nums[r];}};
LeetCode 162. Find Peak Element
class Solution {
public:intfindPeakElement(vector<int>& nums){//这题写法简单,但是思路不明白int l =0, r = nums.size()-1;while(l < r){int mid = l + r >>1;if(nums[mid]> nums[mid+1]) r = mid;else l = mid +1;}return r;}};
LeetCode 155. Min Stack
// MinStack minStack = new MinStack();// minStack.push(-2);// minStack.push(0);// minStack.push(-3);// minStack.getMin(); --> Returns -3.// minStack.pop();// minStack.top(); --> Returns 0.// minStack.getMin(); --> Returns -2.
class MinStack {
public://首先是定义一个栈和一个最小栈
stack<int> stk, stk_min;/** initialize your data structure here. */MinStack(){}//栈里面就随便加,最小栈要比较下,最小栈存的是当前栈中最小的数值//如果比较小,则放入栈中,否则则不放入voidpush(int x){
stk.push(x);if(stk_min.empty()) stk_min.push(x);else stk_min.push(min(x, stk_min.top()));}//弹出的话,就是一起弹处来就可以了voidpop(){
stk.pop();
stk_min.pop();}//栈顶元素inttop(){return stk.top();}//栈顶元素,这里要注意,stack和vector函数有点像,但是不一样呢intgetMin(){return stk_min.top();}};/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(x);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
class Solution {
public:inttrap(vector<int>& height){int res =0;
stack<int> stk;for(int i =0; i < height.size(); i ++){int last =0;while(stk.size()&& height[stk.top()]<= height[i]){int t = stk.top(); stk.pop();
res +=(i - t -1)*(height[t]- last);
last = height[t];}if(stk.size()) res +=(i - stk.top()-1)*(height[i]- last);
stk.push(i);}return res;}};
LeetCode 84. Largest Rectangle in Histogram
class Solution {
public:/*
单调栈:查找每个数左侧第一个比它小的数
单调队列:滑动窗口中的最值
如何枚举处所有的情况呢?
枚举所有柱形的上边界,作为整个矩形的上边界
然后求出左右边界:
1.找出左边离它最近的,比它小的柱形
1.找出右边离它最近的,比它小的柱形
*///首先来说是确认上边界,然后找到左右的边界intlargestRectangleArea(vector<int>& heights){//高度int n = heights.size();//定义两个左右的边界
vector<int>left(n),right(n);//这里是利用单调栈的性质,是一个升序
stack<int> stk;for(int i =0; i < n; i++){while(stk.size()&& heights[stk.top()]>= heights[i])stk.pop();if(stk.empty()) left[i]=-1;else left[i]= stk.top();
stk.push(i);}while(stk.size()) stk.pop();//同理,找到右边界for(int i = n -1; i >=0; i--){while(stk.size()&& heights[stk.top()]>= heights[i]) stk.pop();if(stk.empty()) right[i]= n;else right[i]= stk.top();
stk.push(i);}int res =0;for(int i =0; i < n; i++) res =max(res, heights[i]*(right[i]- left[i]-1));return res;}};
LeetCode 475. Heaters
class Solution {
public:intfindRadius(vector<int>& houses, vector<int>& heaters){
heaters.push_back(INT_MIN), heaters.push_back(INT_MAX);sort(heaters.begin(), heaters.end());int res =0;for(auto&x : houses){int l =0, r = heaters.size()-1;while(l < r){int mid = l + r >>1;if(heaters[mid]>= x) r = mid;else l = mid +1;}
res =max(res,(int)min(heaters[r]-0ll- x, x -0ll- heaters[r-1]));}return res;}};
LeetCode 4. Median of Two Sorted Arrays
class Solution {
public://原问题难以直接递归求解,所以我们从有序数组中,找出第k小数doublefindMedianSortedArrays(vector<int>& nums1, vector<int>& nums2){int total = nums1.size()+ nums2.size();if(total %2==0){int left =findKthNumber(nums1,0, nums2,0, total /2);int right =findKthNumber(nums1,0, nums2,0, total /2+1);return(left + right)/2.0;}else{returnfindKthNumber(nums1,0, nums2,0, total /2+1);}}intfindKthNumber(vector<int>&nums1,int i, vector<int>&nums2,int j,int k){if(nums1.size()- i > nums2.size()- j)returnfindKthNumber(nums2, j, nums1, i, k);if(nums1.size()== i)return nums2[j + k -1];if(k ==1)returnmin(nums1[i], nums2[j]);int si =min(i + k /2,int(nums1.size())), sj = j + k /2;if(nums1[si -1]> nums2[sj -1]){returnfindKthNumber(nums1, i, nums2, j + k /2, k - k /2);}else{returnfindKthNumber(nums1, si, nums2, j, k -(si - i));}}};
LeetCode 239. Sliding Window Maximum
class Solution {
public:
vector<int>maxSlidingWindow(vector<int>& nums,int k){
vector<int> res;
deque<int> q;for(int i =0; i < nums.size(); i ++){if(q.size()&& i - k >= q.front()) q.pop_front();while(q.size()&& nums[q.back()]<= nums[i]) q.pop_back();
q.push_back(i);if(i >= k -1) res.push_back(nums[q.front()]);}return res;}};
LeetCode 456. 132 Pattern
class Solution {
public:
bool find132pattern(vector<int>& nums){int s3 = INT_MIN;
stack<int> stk;for(int i = nums.size()-1; i >=0; i--){if(nums[i]< s3)return true;while(stk.size()&& stk.top()< nums[i]){
s3 = stk.top();
stk.pop();}
stk.push(nums[i]);}return false;}};
哈希表专题
LeetCode 1. Two Sum
class Solution {
public://枚举所有的,如果哈希表中存在则返回
vector<int>twoSum(vector<int>& nums,int target){
unordered_map<int,int> hash;for(int i =0; i < nums.size(); i++){if(hash.count(target - nums[i]))return{hash[target - nums[i]], i};
hash[nums[i]]= i;}return{-1,-1};}};
LeetCode 454. 4Sum II
class Solution {
public:intfourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D){
unordered_map<int,int> hash;//建立哈希表,存储数组A和数组B所有数对求和的结果for(auto a : A)for(auto b : B)
hash[a + b]++;//枚举数组,查询所有相反数的次数int res =0;for(auto c : C)for(auto d : D)
res += hash[- c - d];return res;}};
LeetCode 560. Subarray Sum Equals K
class Solution {
public://这里用到了前缀和和hash表进行查找intsubarraySum(vector<int>& nums,int k){
unordered_map<int,int> hash;
hash[0]=1;int res =0;for(int i =0, sum =0; i < nums.size(); i++){
sum += nums[i];
res += hash[sum - k];
hash[sum]++;}return res;}};
LeetCode 525. Contiguous Array
class Solution {
public:intfindMaxLength(vector<int>& nums){//这里使用前缀和哈希表一起//其中把0转化为-1
unordered_map<int,int> hash;
hash[0]=-1;int res =0, s =0;for(int i =0; i < nums.size(); i++){//前缀和
s += nums[i]*2-1;if(hash.count(s))
res =max(res, i - hash[s]);if(!hash.count(s))
hash[s]= i;}return res;}};
LeetCode 187. Repeated DNA Sequences
class Solution {
public:
vector<string>findRepeatedDnaSequences(string s){
unordered_map<string,int> hash;//插入一个字符串//统计字符串出现的次数
vector<string> res;for(int i =0; i < s.size(); i++){//这里substr的第二个参数是长度,要注意
string str = s.substr(i,10);
hash[str]++;//当然一个字符串可能出现2次以上,我们只记录一次if(hash[str]==2) res.push_back(str);}return res;}};
LeetCode 347. Top K Frequent Elements
class Solution {
public:
vector<int>topKFrequent(vector<int>& nums,int k){//首先用哈希表统计所有数出现的次数//这里使用计序排序的思想,统计出次数最多的前k个元素的下界
unordered_map<int,int> hash;
vector<int> res;for(int x : nums) hash[x]++;int n = nums.size();
vector<int>s(n+1,0);for(auto&p : hash) s[p.second]++;int i = n, t =0;while(t < k) t += s[i--];for(auto&p : hash)if(p.second > i)
res.push_back(p.first);return res;}};
LeetCode 350. Intersection of Two Arrays II
class Solution {
public:
vector<int>intersect(vector<int>& nums1, vector<int>& nums2){
unordered_multiset<int> S;
vector<int> res;for(int x : nums1) S.insert(x);for(int x : nums2)if(S.count(x)){
res.push_back(x);
S.erase(S.find(x));}return res;}};
LeetCode 706. Design HashMap
class MyHashMap {
public:/** Initialize your data structure here. */conststaticint N =20011;
vector<list<pair<int,int>>> hash;MyHashMap(){
hash = vector<list<pair<int,int>>>(N);}
list<pair<int,int>>::iterator find(int key){int t = key % N;auto it = hash[t].begin();for(; it != hash[t].end(); it ++)if(it->first == key)break;return it;}/** value will always be non-negative. */voidput(int key,int value){int t = key % N;auto it =find(key);if(it == hash[t].end())
hash[t].push_back(make_pair(key, value));else
it->second = value;}/** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */intget(int key){auto it =find(key);if(it == hash[key % N].end())return-1;return it->second;}/** Removes the mapping of the specified value key if this map contains a mapping for the key */voidremove(int key){int t = key % N;auto it =find(key);if(it != hash[t].end())
hash[t].erase(it);}};/**
* Your MyHashMap object will be instantiated and called as such:
* MyHashMap obj = new MyHashMap();
* obj.put(key,value);
* int param_2 = obj.get(key);
* obj.remove(key);
*/
LeetCode 652. Find Duplicate Subtrees
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:int cnt =0;
unordered_map<string,int> hash;
unordered_map<int,int> count;
vector<TreeNode*> ans;//只有前序中序和后序并不能唯一确定一颗树,但是把空节点算上的话就可以
string dfs(TreeNode* root){if(!root)returnto_string(hash["#"]);//把树进行编码,同时查找 auto left =dfs(root->left);auto right =dfs(root->right);
string tree =to_string(root->val)+','+ left +','+ right;if(!hash.count(tree)) hash[tree]=++ cnt;int t = hash[tree];
count[t]++;if(count[t]==2) ans.push_back(root);returnto_string(t);}
vector<TreeNode*>findDuplicateSubtrees(TreeNode* root){
hash["#"]=++cnt;dfs(root);return ans;}};
LeetCode 290. Word Pattern
class Solution {
public://n组字母和单词的对应关系//相同字母对应相同单词//不同字母对应不同单词,等价于相同单词对应相同字母
bool wordPattern(string pattern, string str){
stringstream raw(str);
vector<string> words;
string word;while(raw >> word) words.push_back(word);
unordered_map<char, string> PS;
unordered_map<string,char> SP;if(pattern.size()!= words.size())return false;for(int i =0; i < words.size(); i++){char p = pattern[i];
string s = words[i];if(!PS.count(p)) PS[p]= s;if(!SP.count(s)) SP[s]= p;if(PS[p]!= s || SP[s]!= p)return false;}return true;}};
LeetCode 554. Brick Wall
class Solution {
public:intleastBricks(vector<vector<int>>& wall){//不明觉厉
unordered_map<int,int> hash;int res =0;for(auto w : wall){int s =0;for(int i =0; i +1< w.size(); i++){
s += w[i];
res =max(res,++hash[s]);}}return wall.size()- res;}};
LeetCode 149. Max Points on a Line
class Solution {
public://先枚举一个定点,然后将其他点按斜率进行分组,分组使用哈希表intmaxPoints(vector<vector<int>>& points){if(points.empty())return0;int res =1;for(int i =0; i < points.size(); i++){//竖直线需要单独计算//重合点也需要单独计算
unordered_map<longdouble,int> map;int duplicates =0, verticals =1;for(int j = i +1; j < points.size(); j++)if(points[i][0]== points[j][0]){
verticals++;if(points[i][1]== points[j][1]) duplicates++;}for(int j = i +1; j < points.size(); j++)if(points[i][0]!= points[j][0]){longdouble slope =(longdouble)(points[i][1]- points[j][1])/(points[i][0]- points[j][0]);if(map[slope]==0) map[slope]=2;else map[slope]++;
res =max(res, map[slope]+ duplicates);}
res =max(res, verticals);}return res;}};
LeetCode 355. Design Twitter
class Twitter {
public:/** Initialize your data structure here. *///从一个用户映射到他发的微博列表,包括发布的时间,和发布微博的ID
unordered_map<int, vector<pair<int,int>>> posts;//从一个用户映射到他的关注列表
unordered_map<int, unordered_set<int>> follows;int id =0;Twitter(){}/** Compose a new tweet. *///找到用户的列表,然后插入列表voidpostTweet(int userId,int tweetId){
posts[userId].push_back(make_pair(id++, tweetId));}/** Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. */
vector<int>getNewsFeed(int userId){
vector<pair<int,int>> ps;for(auto x : posts[userId]) ps.push_back(x);for(auto follow : follows[userId])for(auto x : posts[follow])
ps.push_back(x);sort(ps.rbegin(), ps.rend());
vector<int> res;for(int i =0; i <10&& i < ps.size(); i++)
res.push_back(ps[i].second);return res;}/** Follower follows a followee. If the operation is invalid, it should be a no-op. */voidfollow(int followerId,int followeeId){if(followerId != followeeId)
follows[followerId].insert(followeeId);}/** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */voidunfollow(int followerId,int followeeId){
follows[followerId].erase(followeeId);}};/**
* Your Twitter object will be instantiated and called as such:
* Twitter* obj = new Twitter();
* obj->postTweet(userId,tweetId);
* vector<int> param_2 = obj->getNewsFeed(userId);
* obj->follow(followerId,followeeId);
* obj->unfollow(followerId,followeeId);
*/
LeetCode 128. Longest Consecutive Sequence
class Solution {
public:intlongestConsecutive(vector<int>& nums){int res =0;
unordered_map<int,int> tr_left, tr_right;for(auto&x : nums){int left = tr_right[x -1];int right = tr_left[x +1];
tr_left[x - left]=max(tr_left[x -left], left +1+ right);
tr_right[x + right]=max(tr_right[x + right], left +1+ right);
res =max(res, left +1+ right);}return res;}};
动态规划专题(2/2)
LeetCode 120. Triangle
class Solution {
public:intminimumTotal(vector<vector<int>>& nums){int n = nums.size();
vector<vector<longlong>>f(2, vector<longlong>(n));
f[0][0]= nums[0][0];for(int i =1; i < n; i++)for(int j =0; j <= i; j++){
f[i &1][j]= INT_MAX;if(j >0) f[i &1][j]=min(f[i &1][j], f[i -1&1][j -1]+ nums[i][j]);if(j < i) f[i &1][j]=min(f[i &1][j], f[i -1&1][j]+ nums[i][j]);}longlong res = INT_MAX;for(int i =0; i < n; i++) res =min(res, f[n-1&1][i]);return res;}};
LeetCode 63. Unique Paths II
class Solution {
public://最后一步可以往下走,最后一步也可往右走intuniquePathsWithObstacles(vector<vector<int>>& g){int n = g.size(), m = g[0].size();
vector<vector<longlong>>f(n, vector<longlong>(m));for(int i =0; i < n; i++)for(int j =0; j < m; j++){if(g[i][j])continue;if(!i &&!j) f[i][j]=1;if(i >0) f[i][j]+= f[i -1][j];if(j >0) f[i][j]+= f[i][j -1];}return f[n-1][m-1];}};
LeetCode 354. Russian Doll Envelopes
class Solution {
public:static bool cmp(const vector<int>& a,const vector<int>& b){return a[0]< b[0]|| a[0]== b[0]&& a[1]> b[1];}intmaxEnvelopes(vector<vector<int>>& envelopes){sort(envelopes.begin(), envelopes.end(), cmp);int n = envelopes.size();
vector<int> dp;for(int i =0; i < n; i ++){int x = envelopes[i][1];auto it =lower_bound(dp.begin(), dp.end(), x);if(it == dp.end()) dp.push_back(x);else*it = x;}return dp.size();}};
LeetCode 338. Counting Bits
class Solution {
public:
vector<int>countBits(int num){
vector<int>f(num+1);
f[0]=0;//举例来说111101一共有5个1//前面已经计算过了11110,只需要再计算最后一个是不是1就可以了for(int i =1; i <= num; i++)
f[i]= f[i >>1]+(i &1);return f;}};
LeetCode 329. Longest Increasing Path in a Matrix
class Solution {
public:int n, m;
vector<vector<int>> f, g;int dx[4]={-1,0,1,0};int dy[4]={0,1,0,-1};intdp(int x,int y){if(f[x][y]!=-1)return f[x][y];
f[x][y]=1;for(int i =0; i <4; i++){int a = x + dx[i];int b = y + dy[i];//结果要比较大if(a >=0&& a < n && b >=0&& b < m && g[a][b]< g[x][y])
f[x][y]=max(f[x][y],dp(a, b)+1);}return f[x][y];}intlongestIncreasingPath(vector<vector<int>>& matrix){if(matrix.empty())return0;
g = matrix;
n = g.size();
m = g[0].size();
f = vector<vector<int>>(n, vector<int>(m,-1));int res =0;//枚举每一个点的结果for(int i =0; i < n; i++)for(int j =0; j < m; j++)
res =max(res,dp(i, j));return res;}};
class Solution {
public:intmaximalSquare(vector<vector<char>>& matrix){if(matrix.empty())return0;int n = matrix.size();int m = matrix[0].size();
vector<vector<int>>f(n +1, vector<int>(m +1,0));int res =0;for(int i =1; i <= n; i++)for(int j =1; j <= m; j++)if(matrix[i -1][j -1]!='0'){
f[i][j]=min(f[i -1][j -1],min(f[i-1][j], f[i][j -1]))+1;
res =max(res, f[i][j]);}return res * res;}};
LeetCode 576. Out of Boundary Paths
class Solution {
public:
vector<vector<vector<int>>> f;int dx[4]={-1,0,1,0};int dy[4]={0,1,0,-1};int mod =1000000007;intfindPaths(int m,int n,int N,int i,int j){
f = vector<vector<vector<int>>>(m, vector<vector<int>>(n, vector<int>(N+1,-1)));returndp(m, n, N, i, j);}intdp(int m,int n,int k,int x,int y){int&v = f[x][y][k];if(v !=-1)return v;
v =0;if(!k)return v;for(int i =0; i <4; i++){int a = x + dx[i], b = y + dy[i];if(a <0|| a == m || b <0|| b == n) v++;else v +=dp(m, n, k-1, a, b);
v %= mod;}return v;}};
LeetCode 91. Decode Ways
class Solution {
public:intnumDecodings(string s){int n = s.size();
vector<int>f(n +1);
f[0]=1;for(int i =1; i <= n; i++){if(s[i -1]!='0') f[i]+= f[i-1];if(i >=2){int t =(s[i -2]-'0')*10+ s[i -1]-'0';if(t >=10&& t <=26) f[i]+= f[i -2];}}return f[n];}};
LeetCode 264. Ugly Number II
class Solution {
public:intnthUglyNumber(int n){
vector<int> q;
q.push_back(1);int a =0, b =0, c =0;for(int i =2; i <= n; i++){int two = q[a]*2, three = q[b]*3, five = q[c]*5;int next =min(two,min(three, five));
q.push_back(next);if(two == next) a++;if(three == next) b++;if(five == next) c++;}return q.back();}};
LeetCode 115. Distinct Subsequences
class Solution {
public:intnumDistinct(string s, string t){int n = s.size(), m = t.size();
vector<vector<longlong>>f(n +1, vector<longlong>(m +1));for(int i =0; i <= n; i++) f[i][0]=1;for(int i =1; i <= n; i++)for(int j =1; j <= m; j++){
f[i][j]= f[i -1][j];if(s[i -1]== t[j -1])
f[i][j]+= f[i -1][j -1];}return f[n][m];}};
LeetCode 132. Palindrome Partitioning II
class Solution {
public:intminCut(string s){int n = s.size();
vector<int>f(n+1);
vector<vector<bool>>st(n, vector<bool>(n, false));for(int i =0; i < n; i++)for(int j = i; j >=0; j--)if(i - j <=1) st[j][i]= s[j]== s[i];else st[j][i]= s[j]== s[i]&& st[j +1][i -1];
f[0]=0;for(int i =1; i <= n; i++){
f[i]= INT_MAX;for(int j =0; j < i; j++)if(st[j][i -1])
f[i]=min(f[i], f[j]+1);}returnmax(0, f[n]-1);}};
LeetCode 526. Beautiful Arrangement
class Solution {
public:intcountArrangement(int N){
vector<int>f(1<< N,0);
f[0]=1;for(int i =0; i <(1<< N); i++){int s =1;for(int j =0; j < N; j++) s += i >> j &1;for(int j =1; j <= N; j++){if(!(i >>(j -1)&1)&&(s %j ==0|| j % s ==0))
f[i |(1<<(j -1))]+= f[i];}}return f[(1<< N)-1];}};
LeetCode 486. Predict the Winner
class Solution {
public:
bool PredictTheWinner(vector<int>& nums){int n = nums.size();
vector<vector<int>>f(n, vector<int>(n,0));for(int i =0; i < n; i++)
f[i][i]= nums[i];for(int len =2; len <= n; len++)for(int i =0; i < n - len +1; i++){int j = i + len -1;
f[i][j]=max(-f[i+1][j]+nums[i],- f[i][j-1]+nums[j]);}return f[0][n -1]>=0;}};