#include <iostream>
#include <vector>
#include <stack>
#include <list>
#include <string>
#include <algorithm>
#include <climits>
#include <unordered_map>
#include <unordered_set>
#include <queue>
using namespace std;
template<typename T>
void print(const vector<T>& nums)
{
for(auto & num : nums)
{
cout << num << " ";
}
cout << endl;
}
template<typename T>
void print1(const vector<T>& nums)
{
for(auto&& num : nums)
{
cout << num << " ";
}
cout << endl;
cout << "=====" << endl;
}
template<typename T>
void print1(const vector<vector<T>>& vecs)
{
for(const vector<T>& nums : vecs)
{
for(auto num : nums)
{
cout << num << " ";
}
cout << endl;
}
cout << "=====" << endl;
}
struct TreeNode
{
int val = 0;
TreeNode* left = nullptr;
TreeNode* right = nullptr;
TreeNode* next = nullptr;
TreeNode(int val_):val(val_),left(nullptr),right(nullptr),next(nullptr)
{
;
}
};
struct LinkNode
{
int val = 0;
LinkNode* next = nullptr;
LinkNode* random = nullptr;
LinkNode(int val_)
{
val = val_;
}
};
int maxCoins(vector<int>& nums) {
nums.insert(nums.begin(),1);
nums.push_back(1);
int n = nums.size();
vector<vector<int>>dp(n,vector<int>(n,0));
for(int len = 2; len < n; ++len)
{
for(int i = 0; i < n -len;++i)
{
int j = i + len;
for(int k = i + 1; k < j; ++k)
{
dp[i][j] = max(dp[i][j],dp[i][k]+dp[k][j]+nums[i]*nums[k]*nums[j]);
}
}
}
return dp[0][n-1];
}
void pre(TreeNode* root)
{
if(nullptr == root)
{
return;
}
cout << root->val << endl;
pre(root->left);
pre(root->right);
}
int getDepth(TreeNode* root)
{
if(nullptr == root)
return 0;
int leftDepth = getDepth(root->left);
int rightDepth = getDepth(root->right);
return 1 + max(leftDepth,rightDepth);
}
vector<int> productExceptSelf(vector<int>& nums)
{
int n = nums.size();
vector<int>ans(n);
ans[0] = 1;
for(int i = 1; i < n; ++i)
ans[i] = nums[i-1] * ans[i-1];
int R = 1;
for(int i = n - 1; i >= 0; --i)
{
ans[i] = ans[i] * R;
R*=nums[i];
}
return ans;
}
string longestPalindrome(string s)
{
int n = s.size();
vector<vector<bool>>dp(n,vector<bool>(n));
int start = 0, end = 0;
for(int i = n - 1; i >= 0; --i)
{
for(int j = i; j < n; ++j)
{
if(s[i] == s[j] && (j - i < 2 || dp[i+1][j-1]))
{
if(end - start < (j - i))
{
start = i;
end = j;
}
dp[i][j] = true;
}
}
}
return s.substr(start,end-start+1);
}
int getDepth_q(TreeNode* root)
{
if(nullptr == root)return 0;
queue<TreeNode*>q;
q.push(root);
int depth = 0;
while(!q.empty())
{
int size = q.size();
++depth;
for(int i = 0; i < size; ++i)
{
TreeNode* cur = q.front();
q.pop();
if(cur->left != nullptr)q.push(cur->left);
if(cur->right != nullptr)q.push(cur->right);
}
}
return depth;
}
void deleteNode(LinkNode* node) {
node->val = node->next->val;
node->next=node->next->next;
}
bool isValid(int row,int col,vector<string>&chessboard,int n)
{
for(int i = 0; i < row; ++i)
{
if(chessboard[i][col] == 'Q')
return false;
}
for(int i = row - 1,j = col - 1; i >= 0 && j >= 0; --i,--j)
{
if(chessboard[i][j] == 'Q')
return false;
}
for(int i = row - 1,j = col + 1; i >= 0 && j < n; --i,++j)
{
if(chessboard[i][j] == 'Q')
return false;
}
return true;
}
void backtrack_help(vector<string>&chessboard,vector<vector<string>>&res,int row,int n)
{
if(row == n)
{
res.push_back(chessboard);
return;
}
for(int col = 0; col < n; ++col)
{
if(isValid(row,col,chessboard,n))
{
chessboard[row][col] = 'Q';
backtrack_help(chessboard,res,row+1,n);
chessboard[row][col] = '.';
}
}
}
vector<vector<string>>solveNqueens(int n)
{
vector<vector<string>>res;
vector<string>chessboard(n,string(n,'.'));
backtrack_help(chessboard,res,0,n);
return res;
}
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int i = m - 1;
int j = n - 1;
int k = m + n - 1;
while(i >= 0 && j >= 0)
{
if(nums1[i] > nums2[j])
{
nums1[k--] = nums1[i--];
}
else
{
nums1[k--] = nums2[j--];
}
}
while(i >= 0)
{
nums1[k--] = nums1[i--];
}
while(j >= 0)
{
nums1[k--] = nums2[j--];
}
}
vector<int>dailyTemperatures(const vector<int>& tmp)
{
int n = tmp.size();
vector<int>res(n);
stack<int>st;
for(int i = n - 1; i >= 0; --i)
{
while(!st.empty() && tmp[i] >= tmp[st.top()])st.pop();
res[i] = st.empty() ? 0 : st.top() - i;
st.push(i);
}
return res;
}
bool isValidBST(TreeNode* root)
{
//递归
// if(root == nullptr)return true;
// bool left = isValidBST(root->left);
// bool right = isValidBST(root->right);
// if(!left)return false;
// if(root->val_ <= preV)return false;
// return isValidBST(root->right);
//递归
//非递归
TreeNode* pre = nullptr;
stack<TreeNode*>st;
while(root!= nullptr||!st.empty())
{
while(root != nullptr)
{
st.push(root);
root = root->left;
}
root = st.top();
st.pop();
if(pre!= nullptr && root->val <=pre->val)return false;
pre = root;
root=root->right;
}
return true;
// return isValidBST(root, -1, -1);
}
bool isValid(vector<vector<string>>&board,int i, int j, char c)
{
for(int row = 0; row < 9; ++row)
{
if(board[row][j][0] == c)return false;
}
for(int col = 0; col < 9; ++col)
{
if(board[i][col][0] == c)return false;
}
int rowIndex = (i / 3) * 3,colIndex = (j / 3) * 3;
for(int m = rowIndex; m < rowIndex + 3; ++m)
{
for(int n = colIndex; n < colIndex + 3; ++n)
{
if(board[m][n][0]==c)return false;
}
}
return true;
}
bool solve(vector<vector<string>>&board)
{
int m = board.size(),n = board[0].size();
for(int i = 0; i < m; ++i)
{
for(int j = 0;j < n; ++j)
{
if(board[i][j] == ".")
{
for(char c = '1'; c <= '9'; ++c)
{
if(isValid(board,i,j,c))
{
board[i][j][0] = c;
if(solve(board))return true;
else board[i][j] = ".";
}
}
return false;
}
}
}
return true;
}
vector<vector<string>> solveSudoku(vector<vector<string>>& board) {
solve(board);
return board;
}
LinkNode* generateLinkNode(vector<int>& nums)
{
int n = nums.size();
LinkNode dummy(0);
LinkNode* head = &dummy;
for(int i = 0; i < n; ++i)
{
LinkNode* cur = new LinkNode(nums[i]);
head->next = cur;
head = head->next;
}
return dummy.next;
}
int minPathSum(vector<vector<int>>& grid)
{
int m = grid.size(), n = grid[0].size();
for(int i = 0; i < m; ++i)
{
for(int j = 0; j < n; ++j)
{
if(i == 0)grid[i][j] += grid[i][j-1];
else if(j == 0)grid[i][j] += grid[i-1][j];
else
grid[i][j]+=min(grid[i-1][j],grid[i][j-1]);
}
}
return grid[m-1][n-1];
}
int partition(vector<int>& nums,int left,int right)
{
int piv = nums[right];
int start = left,end = right -1;
while(start <= end)
{
if(nums[start] < piv)++start;
else if(nums[end]>piv)--end;
else
{
swap(nums[start++],nums[end--]);
}
}
swap(nums[start],nums[right]);
return start;
}
void helper(vector<int>& nums,int left,int right)
{
if(left > right)return;
int pi = partition(nums,left,right);
helper(nums,left,pi-1);
helper(nums,pi+1,right);
return;
}
vector<pair<int,int>>dirs{{0,-1},{0,1},{1,0},{-1,0}};
class DSU{
vector<int>parent_;
public:
DSU(int N)
{
parent_.resize(N);
for(int i = 0; i < N; ++i)
{
parent_[i] = i;
}
}
int find(int x)
{
if(parent_[x] != x)parent_[x] = find(parent_[x]);
return parent_[x];
}
void Union(int x, int y)
{
parent_[find(x)] = find(y);
}
};
void bfs(vector<vector<string>>& grid, int i ,int j)
{
queue<pair<int,int>>q;
q.push({i,j});
while(!q.empty())
{
auto cur = q.front();
q.pop();
int x = cur.first,y = cur.second;
if(x < 0 || x >= grid.size() || y < 0 || y >= grid[0].size() || grid[x][y] == "0")continue;
grid[x][y] = "0";
for(auto dir:dirs)
{
q.push({x+dir.first,y+dir.second});
}
}
}
void dfs_stack(vector<vector<string>>&grid,int i,int j)
{
stack<pair<int,int>>st;
st.push({i,j});
while(!st.empty())
{
auto cur = st.top();
st.pop();
int x = cur.first, y = cur.second;
if(x < 0 || x >= grid.size() || y < 0 || y >= grid[0].size() || grid[x][y] == "0")continue;
grid[x][y] = "0";
for(auto p:dirs)
{
st.push({x + p.first,y+p.second});
}
}
}
vector<int> findDisappearedNumbers(vector<int>& nums) {
int n = nums.size();
vector<int>a(n+1);
vector<int> v;
for(int i=0;i<n;i++)
++a[nums[i]];
for(int i=1;i<=n;i++){
if(0 == a[i])
{
v.push_back(i);
}
}
return v;
}
int maximalSquare(vector<vector<char>>& matrix) {
int m = matrix.size(), n = matrix[0].size();
if(m == 0 || n == 0)return 0;
vector<vector<int>>dp(m+1,vector<int>(n+1,0));
int res = 0;
for(int i = 1; i <= m; ++i)
{
for(int j = 1; j <= n; ++j)
{
if('1' == matrix[i-1][j-1])
{
dp[i][j] = 1 + min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1]));
res = max(res,dp[i][j]);
}
}
}
return res * res;
}
void dfs(vector<vector<string>>&grid,int i, int j)
{
if(i < 0 || i >= grid.size() || j < 0 || j >= grid[0].size() || grid[i][j] == "0")
return ;
grid[i][j] = "0";
dfs(grid,i-1,j);
dfs(grid,i+1,j);
dfs(grid,i,j-1);
dfs(grid,i,j+1);
return;
}
int numIslands(vector<vector<string>>&grid)
{
int m = grid.size(), n = grid[0].size(),res = 0;
// DSU dsu(m*n);
for(int i = 0; i < m ;++i)
{
for(int j = 0; j < n; ++j)
{
if(grid[i][j] == "1")
{
++res;
// dfs_stack(grid,i,j);
// bfs(grid,i,j);
dfs(grid,i,j);
// DSU
// for(const pair<int,int>p:dirs)
// {
// int x = i + p.first, y = j + p.second;
// if(x >= 0 && y >= 0 && x < m && y < n && grid[x][y] == "1")
// {
// if(dsu.find(x*n+y)!=dsu.find(i*n+j)) --res;
// dsu.Union(x*n+y,i*n+j);
// }
// }
}
}
}
return res;
}
vector<int>robSub(TreeNode* root)
{
if(nullptr == root)return {0,0};
vector<int>leftV = robSub(root->left);
vector<int>rightV = robSub(root->right);
int rob = root->val + leftV[0] + rightV[0];
int notRob = max(leftV[0],leftV[1]) + max(rightV[0],rightV[1]);
return {notRob,rob};
}
int rob1(TreeNode* root)
{
if(nullptr == root)return 0;
vector<int>res = robSub(root);
return max(res[0],res[1]);
}
int removeElement(vector<int>& nums,int val)
{
int n = nums.size();
int left = 0;
for(int right = 0;right < n; ++right)
{
if(nums[right]!=val)
{
nums[left++] = nums[right];
}
}
return left;
}
vector<int>qs(const vector<int>& v)
{
vector<int>nums = v;
int n = nums.size();
helper(nums,0,n-1);
return nums;
}
void heapify(vector<int>& nums,int n,int i)
{
int largest = i;
int l = 2 * i + 1;
int r = 2 * i + 2;
while(l < n && nums[largest] < nums[l])
{
largest = l;
}
while(r < n && nums[largest] < nums[r])
{
largest = r;
}
if(largest != i)
{
swap(nums[largest],nums[i]);
heapify(nums,n,largest);
}
}
vector<int>hpS(const vector<int>& boxes)
{
vector<int>nums = boxes;
int n = nums.size();
for(int i = n / 2 - 1; i >= 0; --i)
{
heapify(nums,n,i);
}
for(int i = n-1; i>=0;--i)
{
swap(nums[0],nums[i]);
heapify(nums,i,0);
}
return nums;
}
int reverse1(int x)
{
long ret = 0;
while(x!=0)
{
ret = ret * 10 + x % 10;
x /= 10;
}
return (int)ret == ret ? (int)ret : 0;
}
int trap(const vector<int>& height)
{
int res = 0;
int n = height.size();
vector<int>left(n),right(n);
left[0] = height[0];
right[n-1] = height[n-1];
for(int i = 1; i < n; ++i)
{
left[i] = max(height[i],left[i-1]);
}
for(int i = n - 2; i >= 0; --i)
{
right[i] = max(height[i],right[i+1]);
}
for(int i = 0; i < n; ++i)
{
res += min(left[i],right[i]) - height[i];
}
return res;
}
int trapI(const vector<int>& nums)
{
int left = 0, right = nums.size() - 1,res = 0;
while(left < right)
{
int area = min(nums[left],nums[right])*(right - left);
res = max(res,area);
if(nums[left] < nums[right])++left;
else --right;
}
return res;
}
LinkNode* addTwoNumbers(LinkNode* l1, LinkNode* l2) {
LinkNode* head = new LinkNode(-1);
LinkNode* cur = head;
int sum = 0;
bool carry = false;
while(l1 || l2)
{
sum = 0;
if(l1)
{
sum += l1->val;
l1 = l1->next;
}
if(l2)
{
sum+=l2->val;
l2=l2->next;
}
if(carry)++sum;
cur->next = new LinkNode(sum % 10);
cur=cur->next;
carry = sum >= 10 ? true:false;
}
if(carry)cur->next = new LinkNode(1);
return head->next;
}
int rain(const vector<int>& height)
{
int n = height.size(),res = 0;
vector<int>left(n),right(n);
left[0] = height[0];
right[n-1] = height[n-1];
for(int i = 1; i < n; ++i)
{
left[i] = max(height[i],left[i-1]);
}
for(int i = n - 1; i >= 0; --i)
{
right[i] = max(height[i],right[i+1]);
}
for(int i = 0; i < n; ++i)
{
res += min(left[i],right[i]) - height[i];
}
return res;
}
int maxlength = INT_MIN;
int GetHeight(TreeNode* root)
{
if(nullptr == root)return 0;
return 1 + max(GetHeight(root->left),GetHeight(root->right));
}
void df_s(TreeNode* root)
{
if(nullptr == root)return;
df_s(root->left);
df_s(root->right);
maxlength = max(maxlength,GetHeight(root->left) + GetHeight(root->right));
}
int diameterOfBinaryTree(TreeNode* root)
{
if(nullptr == root)return 0;
df_s(root);
return maxlength;
}
int rainI(const vector<int>& nums)
{
stack<int>st;
int res = 0,n = nums.size();
for(int i = 0; i < n; ++i)
{
while(!st.empty() && nums[i] > nums[st.top()])
{
int pre = st.top();
st.pop();
if(st.empty())break;
int minHeight = min(nums[i],nums[st.top()]);
res += (minHeight - nums[pre]) * (i - st.top() - 1);
// res += (minHeight - nums[pre]) * ( i - st.top() - 1);
}
st.push(i);
}
return res;
}
LinkNode* detectCycleNode(LinkNode* head)
{
LinkNode* slow = head, *fast = head;
while(fast != nullptr && fast->next != nullptr)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
{
fast = head;
while(fast != slow)
{
fast = fast->next;
slow = slow->next;
}
return slow;
}
}
return nullptr;
}
void moveZeroes(vector<int>& nums) {
int n = nums.size();
if(1 == n)return;
for(int zero=0,nonzero =1 ;nonzero < n && zero < n; ++nonzero)
{
if(nums[nonzero]!=0 && nums[zero]==0)swap(nums[zero],nums[nonzero]);
while(nums[zero]!=0 && zero < nonzero)++zero;
}
}
int result = 0;
void dfs(TreeNode* node, int sum)
{
if(nullptr == node)return;
if(sum - node->val == 0)++result;
dfs(node->left,sum-node->val);
dfs(node->right,sum-node->val);
}
int pathSum(TreeNode* node,int sum)
{
if(nullptr == node)return 0;
dfs(node,sum);
pathSum(node->left,sum);
pathSum(node->right,sum);
return result;
}
void sortColors(vector<int>& nums) {
int cur = 0,left = 0,right = nums.size() - 1;
while(cur <= right)
{
if(2 == nums[cur])
{
swap(nums[cur],nums[right--]);
}
else if(0 == nums[cur])
{
swap(nums[cur++],nums[left++]);
}
else
{
++cur;
}
}
}
int longestConsecutive(vector<int>& nums) {
int res = 0;
unordered_set<int>set;
for(auto & num :nums)set.insert(num);
for(auto x:set)
{
if(!set.count(x-1))
{
int y = x;
while(set.count(y+1))
{
++y;
}
res = max(res,y-x+1);
}
}
return res;
}
vector<vector<int>> levelOrder(TreeNode* node)
{
vector<vector<int>>res;
if(nullptr == node)return res;
queue<TreeNode*>q;
q.push(node);
while (!q.empty())
{
int size = q.size();
vector<int>v;
for(int i = 0; i < size; ++i)
{
TreeNode* cur = q.front();
q.pop();
v.push_back(cur->val);
if(cur->left != nullptr)q.push(cur->left);
if(cur->right != nullptr)q.push(cur->right);
}
res.push_back(v);
}
return res;
}
void levelOrder(TreeNode* root,vector<vector<int>>& res)
{
queue<TreeNode*>q;
if(root != nullptr)q.push(root);
while(!q.empty())
{
int size = q.size();
vector<int>tmp;
for(int i = 0; i < size; ++i)
{
auto cur = q.front();
q.pop();
tmp.push_back(cur->val);
if(cur->left)q.push(cur->left);
if(cur->right)q.push(cur->right);
}
res.push_back(tmp);
}
return ;
}
int maxProfit_II(const vector<int>& prices)
{
if(prices.empty())return 0;
int n = prices.size();
vector<vector<int>>dp(n,vector<int>(2));
dp[0][0] = 0;
dp[0][1] = -prices[0];
for(int i = 1; i < n; ++i)
{
dp[i][1] = max(dp[i-1][1],dp[i-1][0] - prices[i]);
dp[i][0] = max(dp[i-1][0],dp[i-1][1] + prices[i]);
}
return dp[n-1][0];
}
int maxProfit_II_greedy(const vector<int>& prices)
{
if(prices.empty())return 0;
int n = prices.size();
int profit = 0;
for(int i = 1; i < n; ++i)
{
if(prices[i-1] < prices[i])
{
profit += (prices[i] - prices[i-1]);
}
}
return profit;
}
bool isValid(const string s)
{
stack<char>st;
for(char c : s)
{
if(c == '(')
{
st.push(')');
}
else if(c == '{')
{
st.push('}');
}
else if(c == '[')
{
st.push(']');
}
else if(st.empty() || st.top() != c)
{
return false;
}
else
{
st.pop();
}
}
return st.empty();
}
bool isValids(string& s){ //判断当前字符串是否括号匹配
int i,len=s.length();
int cnt=0;
for(i=0; i<len; i++){
if(s[i] == '(') cnt++;
else if(s[i]==')'){
cnt--;
if(cnt < 0) return false;
}
}
return cnt==0;
}
vector<string> ans;
void dfs(string s,int now,int left,int right){
if(left==0 && right == 0){
if(isValids(s)) ans.push_back(s);
}else{
int len=s.length();
for(int i=now; i<len; i++){
if(s[i] == '(' && left>0){ //删除左括号
dfs(s.substr(0,i)+s.substr(i+1),i,left-1,right);
while(i+1<len && s[i+1]=='(') i++; //连续的左括号,我们删除第一个就可以了
}else if(s[i]==')' && right>0){ //删除右括号
dfs(s.substr(0,i)+s.substr(i+1),i,left,right-1);
while(i+1<len && s[i+1]==')') i++; //连续的右括号,我们删除第一个就可以了
}
}
}
}
vector<string> removeInvalidParentheses(string s) {
int len=s.length();
int left=0,right=0;
for(int i=0; i<len; i++){ //统计多出来的左括号、右括号数目
if(s[i] == '(') left++;
else if(s[i] == ')'){
if(left>0) left--;
else right++;
}
}
dfs(s,0,left,right);
return ans;
}
LinkNode* reverseBetween(LinkNode* head,int m, int n)
{
LinkNode dummy(-1);
dummy.next = head;
LinkNode* pre = &dummy;
LinkNode* cur = dummy.next;
int i = 1;
while(i < m)
{
pre = cur;
cur = cur->next;
++i;
}
LinkNode* node = pre;
while(i ++ <= n)
{
LinkNode* next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
node->next->next = cur;
node->next = pre;
return dummy.next;
}
bool isValid1(string s)
{
stack<char>st;
for(int i = 0; i < s.size(); ++i)
{
char c = s[i];
if(c == '[')st.push(']') ;
else if(c == '{')st.push('}');
else if(c == '(')st.push(')');
else if(st.empty() || st.top() != c)return false;
else st.pop();
}
return st.empty();
}
bool canPartition(const vector<int>& nums)
{
int sum = accumulate(nums.begin(),nums.end(),0);
if(sum % 2 == 1)return false;
int target = sum / 2;
vector<int>dp(10001,0);
for(int i = 0; i < nums.size(); ++i)
{
for(int j = target; j >= nums[i]; --j)
{
dp[j] = max(dp[j],dp[j-nums[i]]+nums[i]);
}
}
return dp[target]==target;
}
// bool isMatch(string s, string p) {
// bool dp[s.length()+1][p.length()+1] = {};
// dp[s.length()][p.length()] = 1;
// for (int i = s.length(); i >= 0; i--){
// for (int j = p.length() - 1; j >= 0; j--){
// bool first_match = i < s.length() && (p[j] == s[i] || p[j] == '.');
// if (j + 1 < p.length() && p[j+1] == '*'){
// dp[i][j] = dp[i][j+2] || first_match && dp[i+1][j];
// }
// else {
// dp[i][j] = first_match && dp[i+1][j+1];
// }
// }
// }
// return dp[0][0];
// }
// bool isMatchI(string s,string p)
// {
// int m = s.size(), n = p.size();
// bool dp[m+1][n+1];
// dp[m][n] = 1;
// for(int i = m; i >=0; --i)
// {
// for(int j = n - 1;j >= 0;--j)
// {
// bool first_match = i < m && (s[i] == p[j] || p[j] == '.');
// if(j + 1 < p.size() && p[j+1] == '*')
// {
// dp[i][j] = dp[i][j+2] || first_match && dp[i+1][j];
// }
// else
// {
// dp[i][j] = first_match && dp[i+1][j+1];
// }
// }
// }
// return dp[0][0];
// }
TreeNode* mergeTree(TreeNode* t1, TreeNode* t2)
{
if(nullptr == t1)return t2;
if(nullptr == t2)return t1;
t1->val += t2->val;
t1->left = mergeTree(t1->left,t2->left);
t1->right = mergeTree(t1->right,t2->right);
return t1;
}
TreeNode* mergeTree_q(TreeNode* t1, TreeNode* t2)
{
if(nullptr == t1)return t2;
if(nullptr == t2)return t1;
queue<TreeNode*>q;
q.push(t1);
q.push(t2);
while(!q.empty())
{
TreeNode* n1 = q.front();q.pop();
TreeNode* n2 = q.front();q.pop();
n1->val += n2->val;
if(n1->left != nullptr && n2->left != nullptr)
{
q.push(n1->left);
q.push(n2->left);
}
if(n1->right != nullptr && n2->right != nullptr)
{
q.push(n1->right);
q.push(n2->right);
}
if(n1->left == nullptr && n2->left != nullptr)
{
n1->left = n2->left;
}
if(n1->right == nullptr && n2->right != nullptr)
{
n1->right = n2->right;
}
}
return t1;
}
void rotate1(vector<vector<int>>& matrix)
{
int n = matrix.size();
for(int i = 0; i < n; ++i)
{
for(int j = 0; j < i; ++j)
{
int tmp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = tmp;
}
}
for(int i = 0; i < n; ++i)
{
for(int j = 0; j < n / 2; ++j)
{
int tmp = matrix[i][j];
matrix[i][j] = matrix[i][n-1-j];
matrix[i][n-1-j]=tmp;
}
}
}
bool isMatch(string s, string p)
{
int m = s.size(), n = p.size();
bool dp[m+1][n+1];
dp[m][n] = 1;
for(int i = n; i >= 0; --i)
{
for(int j = n - 1; j >= 0; --j)
{
bool first_match = i < m && (s[i] == p[j] || p[j] == '.');
if(j+1 < n && p[j+1] == '*')
{
dp[i][j] = dp[i][j+2] || first_match && dp[i+1][j];
}
else
{
dp[i][j] = first_match && dp[i+1][j+1];
}
}
}
return dp[0][0];
}
int maxVal = INT_MIN;
int helper(TreeNode* root)
{
if(root == nullptr)return 0;
int left = max(0, helper(root->left));
int right = max(0,helper(root->right));
maxVal = max(maxVal,left + right + root->val);
return max(left,right) + root->val;
}
int maxSum(TreeNode* root)
{
helper(root);
return maxVal;
}
class MinStack
{
public:
stack<int>st,minSt;
void push(int x)
{
st.push(x);
if(minSt.empty() || x <= minSt.top())minSt.push(x);
}
void pop()
{
int top = st.top();
if(top == minSt.top())minSt.pop();
}
int top(){return st.top();}
int getMin(){return minSt.top();}
};
vector<vector<int>>visited;
vector<vector<int>>dirss{{0,-1},{0,1},{1,0},{-1,0}};
bool dfs0(vector<vector<char>>& board,string word,int index,int x,int y)
{
if(board[x][y] != word[index])return false;
if(index == word.size() - 1)return true;
visited[x][y] = 1;
for(const auto& dir:dirss)
{
if(x+dir[0] < 0 || x + dir[0] >= board.size() || y + dir[1] < 0 || y + dir[1] >= board[0].size() || visited[x+dir[0]][y+dir[1]])
continue;
if(dfs0(board,word,index + 1,x+dir[0],y+dir[1]))return true;
}
visited[x][y] = 0;
return false;
}
bool exist(vector<vector<char>>& board,string word)
{
int m = board.size(), n = board[0].size();
visited = vector<vector<int>>(m,vector<int>(n,0));
for(int i = 0;i < m; ++i)
{
for(int j = 0;j < n; ++j)
{
if(dfs0(board,word,0,i,j))return true;
}
}
return false;
}
int removeDuplicates(vector<int>& nums) {
int n = nums.size();
if(n <= 1)
return n;
int i = 0;
for(int j = 1; j < n; ++j){
if(nums[j] != nums[i]){
i++;
nums[i] = nums[j];
}
}
for(;i + 1 < n; ++i)
{
nums[i+1] = 0;
}
return i+1;
}
int romanToInt(string s)
{
int ral = 0;
unordered_map<char, int>bp = { { 'I',1 },{ 'V', 5 },{ 'X', 10 },{ 'L' , 50 },{ 'C' , 100 },{ 'D' , 500 },{ 'M' , 1000 } };
int s_size = s.size();
for (int i = 0; i < s_size; i++)
{
int res = bp[s[i]];
if (i == s_size - 1 || bp[s[i + 1]] <= bp[s[i]]) ral += res;
else ral -= res;
}
return ral;
}
vector<vector<int>>fourSum(vector<int>& nums, int target)
{
sort(nums.begin(), nums.end());
vector<vector<int>>res;
int n = nums.size(), left, right, sum;
for (int i = 0; i < n - 3; ++i)
{
if (i != 0 && nums[i] == nums[i - 1])continue;
for (int j = i + 1; j < n - 2; ++j)
{
if (j != i + 1 && nums[j] == nums[j - 1])continue;
left = j + 1, right = n - 1;
while (left < right)
{
sum = nums[i] + nums[j] + nums[left] + nums[right];
if (target == sum)
{
res.push_back({ nums[i],nums[j],nums[left++],nums[right--] });
while (left < right && nums[left] == nums[left - 1]) ++left;
while (left < right && nums[right] == nums[right + 1])--right;
}
else if (sum > target)--right;
else ++left;
}
}
}
return res;
}
void backtrackI(const vector<int>& candidates,int target,vector<int>&path,vector<vector<int>>&res,int sum, int index)
{
if(sum > target)return;
if(sum == target)
{
res.push_back(path);
return;
}
for(int i = index ; i < candidates.size(); ++i)
{
sum += candidates[i];
path.push_back(candidates[i]);
backtrackI(candidates,target,path,res,sum,i);
path.pop_back();
sum -= candidates[i];
}
}
int strStr(string haystack,string needle)
{
int n = haystack.size(),m = needle.size();
for(int i = 0;i + m <= n;++i)
{
bool flag = true;
for(int j = 0; j < m; ++j)
{
if(haystack[i+j]!=needle[j]){
flag = false;
break;
}
}
if(flag)return i;
}
return -1;
}
int subarraySum(const vector<int>& nums,int target)
{
unordered_map<int,int>map;
int sum = 0, res = 0;
map[0] = 1;
for(int num:nums)
{
sum += num;
if(map.count(sum - target))res+=map[sum - target];
++map[sum];
}
return res;
}
vector<vector<int>>combinationSum(const vector<int>& candidates, int target)
{
vector<vector<int>>res;
vector<int>path;
backtrackI(candidates,target,path,res,0,0);
return res;
}
bool hasCycleNode(LinkNode* head)
{
LinkNode* slow = head, *fast = head;
while(fast != nullptr && fast->next != nullptr)
{
slow = slow->next;
fast = fast->next->next;
if(slow == fast) return true;
}
return false;
}
bool cmp1(pair<int,int>p1,pair<int,int>p2)
{
return p1.first < p2.first;
}
vector<pair<int,int>>merge(vector<pair<int,int>>& intervals)
{
vector<pair<int,int>>res;
int n = intervals.size();
if(n == 0)return res;
sort(intervals.begin(),intervals.end(),cmp1);
auto cur = intervals[0];
for(auto next : intervals)
{
if(cur.second >= next.first)cur.second = max(cur.second,next.second);
else
{
res.push_back(cur);
cur = next;
}
}
res.push_back(cur);
return res;
}
int str2int(string str)
{
if(str.empty())return 0;
int len = str.size();
int pos = str.find_first_not_of(" ");
if(-1 != pos)str = str.substr(pos,len - pos + 1);
bool flag = false;
long long res = 0;
if((str[0] <= '9' && str[0] >= 0) || str[0] == '+' || str[0] == '-')
{
int i = 0;
if('+' == str[0])i = 1;
else if('-' == str[0]){
i = 1;
flag = true;
}
for(;i < str.size(); ++i)
{
if(str[i] <= '9' && str[i] >= '0')
{
res = res * 10 + (str[i]-'0');
if(res > INT_MAX)
{
if(flag)return INT_MIN;
else return INT_MAX;
}
}
else break;
}
}
else return 0;
if(flag)
{
res = -res;
}
return res;
}
int numDecodings(string s)
{
int n = s.size();
vector<int>dp(n+1);
dp[n] = 1;
if(s[n-1]!='0')
{
dp[n-1]=1;
}
for(int i = n - 2; i >= 0; --i)
{
if(s[i] == '0')continue;
int ans1 = dp[i+1];
int ans2 = 0;
int ten = (s[i] -'0') * 10;
int one = s[i+1] - '0';
if(ten + one <= 26)
{
ans2 = dp[i+2];
}
dp[i] = ans1 + ans2;
}
return dp[0];
}
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string,vector<string>>map;
string res;
for(auto& it:strs)
{
res = it;
sort(res.begin(),res.end());
map[res].push_back(move(it));
}
vector<vector<string>>ret;
for(auto& it : map)
{
ret.push_back(move(it.second));
}
return ret;
}
int preOrderIndex = 0;
TreeNode* help(vector<int>&pre,int start,int end,unordered_map<int,int>&map)
{
if(start > end)return nullptr;
TreeNode* root = new TreeNode(pre[preOrderIndex++]);
int index = map[root->val];
root->left = help(pre,start,index-1,map);
root->right = help(pre,index+1,end,map);
return root;
}
TreeNode* buildTreeFromPreIn(vector<int>&pre,vector<int>&in)
{
int N = pre.size();
unordered_map<int,int>map;
for(int i = 0; i < N; ++i)
{
map[in[i]] = i;
}
return help(pre,0,N-1,map);
}
int removeDuplicatesI(vector<int>& nums)
{
int n = nums.size();
int i = 0;
for(int j = 1; j < n; ++j)
{
if(nums[i]!=nums[j])
{
nums[i++] = nums[j];
}
}
for(;i + 1 < n; ++i)
{
nums[i+1] = 0;
}
return i+1;
}
int singleNum0(const vector<int>& nums)
{
int res = 0;
for(auto & num :nums)
{
res ^= num;
}
return res;
}
bool cmpp(pair<int,int>&m,pair<int,int>&n)
{
return m.second > n.second;
}
vector<int> topKFrequent(vector<int>& nums,int k)
{
unordered_map<int,int>m;
for(int i = 0 ; i < nums.size(); ++i)
{
++m[nums[i]];
}
vector<pair<int,int>>mp_sort(m.begin(),m.end());
sort(mp_sort.begin(),mp_sort.end(),cmpp);
vector<int>res;
auto iter = mp_sort.begin();
while(k--)
{
res.push_back(iter->first);
++iter;
}
return res;
}
int countSubStrings(string s)
{
int n = s.size(),res = 0;
vector<vector<bool>>dp(n,vector<bool>(n,false));
for(int i = n - 1; i >= 0; --i)
{
for(int j = i; j <= s.size(); ++j)
{
if(s[i] == s[j])
{
if(j - i <= 1)
{
++res;
dp[i][j] = true;
}
else if(dp[i+1][j-1])
{
++res;
dp[i][j] = true;
}
}
}
}
return res;
}
int hammingDistance(int x, int y) {
int z=x^y;
int count=0;
//计算二进制中1的个数
while(z){
++count;
z=(z-1)&z;
}
return count;
}
TreeNode* invertTree(TreeNode* node)
{
if(nullptr == node)return nullptr;
swap(node->left,node->right);
invertTree(node->left);
invertTree(node->right);
return node;
}
double findMediaSorted(const vector<int>&n1,const vector<int>& n2)
{
int m = n1.size(),n = n2.size();
if(m > n)return findMediaSorted(n2,n1);
int left = 0, right = m;
while(left <= right){
int x = left + (right - left ) / 2;
int y = (m + n + 1) / 2 - x;
int xLeft = (x == 0) ? INT_MIN : n1[x-1];
int xRight = (x == m) ? INT_MAX : n1[x];
int yLeft = (y == 0) ? INT_MIN : n2[y-1];
int yRight = (y == n) ? INT_MAX : n2[y];
if(xLeft <= yRight && yLeft <= xRight)
{
if((m + n) % 2 == 0)return (double)(max(xLeft,yLeft), min(xRight,yRight)) / 2.0;
else return (double)max(xLeft,yLeft);
}
else if(xRight > yLeft) right = x - 1;
else left = x + 1;
}
return -1;
}
TreeNode* dfs_invertTree(TreeNode* node)
{
if(nullptr == node)return nullptr;
stack<TreeNode*>st;
st.push(node);
while(!st.empty())
{
TreeNode* cur = st.top();
st.pop();
swap(cur->left,cur->right);
if(cur->right != nullptr)st.push(cur->right);
if(cur->left != nullptr)st.push(cur->left);
}
return node;
}
TreeNode* bfs_invertTree(TreeNode* node)
{
if(nullptr == node)return nullptr;
queue<TreeNode*>q;
q.push(node);
while (!q.empty())
{
int size = q.size();
for(int i = 0; i < size; ++i)
{
TreeNode* cur = q.front();
q.pop();
swap(cur->left,cur->right);
if(cur->left != nullptr)q.push(cur->left);
if(cur->right != nullptr)q.push(cur->right);
}
}
return node;
}
string decodeString(string s) {
int num=0;
string str="";
stack<int> numstk;
stack<string> strstk;
for(int i=0;i<(int)s.size();++i){
if(s[i]>='0'&&s[i]<='9'){
num=10*num+s[i]-'0';
}
else if(s[i]>='a'&&s[i]<='z'||s[i]>='A'&&s[i]<='Z'){
str+=s[i];
}
else if(s[i]=='['){
numstk.push(num);
num=0;
strstk.push(str);
str="";
}
else if(s[i]==']'){
int time=numstk.top();
numstk.pop();
for(int i=0;i<time;++i)
strstk.top()+=str;
str=strstk.top();
strstk.pop();
}
}
return str;
}
// void dfs(int left, int right, string level,vector<string>&res)
// {
// if(left > right)return;
// if(left == 0 && right == 0)res.emplace_back(level);
// if(left > 0)dfs(left - 1, right,level + "(",res);
// if(right > 0)dfs(left,right - 1,level+")",res);
// return ;
// }
// vector<string> generateParentheses(int n)
// {
// vector<string>res;
// dfs(n,n,"",res);
// return res;
// }
void dfs(int left, int right, string tmp,vector<string>&res)
{
if(left > right)return;
if(0 == left && 0 == right)res.emplace_back(tmp);
if(left > 0)dfs(left-1,right,tmp + "(",res);
if(right > 0)dfs(left,right-1,tmp +")",res);
return;
}
vector<vector<int>> reconstructQueue(vector<vector<int>>& people)
{
sort(people.begin(),people.end(),[](const vector<int> &a, const vector<int>& b) {
if(a[0] == b[0]) return a[1] < b[1]; else return a[0] > b[0];});
vector<vector<int>>q;
for(int i = 0; i < people.size(); ++i)
{
int pos = people[i][1];
q.insert(q.begin()+pos,people[i]);
}
return q;
}
vector<string> gen(int n)
{
vector<string>res;
dfs(n,n,"",res);
return res;
}
vector<int>singleNum(vector<int>& nums)
{
int res = 0;
for(int i = 0; i < nums.size(); ++i)
{
res ^= nums[i];
}
int tmp = 1;
while((res & tmp) == 0)
{
tmp <<= 1;
}
int ans2 = 0;
for(int i = 0; i < nums.size(); ++i)
{
if((tmp&nums[i])!= 0)
{
ans2 ^= nums[i];
}
}
vector<int> rtn;
rtn.push_back(ans2);
rtn.push_back(ans2 ^ res);
return rtn;
}
string convert(string s, int numRows) {
if(numRows <= 1)return s;
vector<string>zigzag(min(numRows,static_cast<int>(s.size())));
int curRow = 0;
bool goDown = false;
for(int i = 0; i < s.size(); ++i)
{
zigzag[curRow]+=s[i];
if(0 == curRow || curRow == numRows - 1)goDown = !goDown;
curRow+=goDown?1:-1;
}
string res("");
for(auto &str:zigzag)res+=str;
return res;
}
void print(const vector<pair<int,int>>& vs)
{
for(auto v:vs)
{
cout << v.first << " " << v.second << endl;
}
}
vector<TreeNode*>help(int st,int ed)
{
vector<TreeNode*>res;
if(st > ed)res.push_back(nullptr);
for(int i = st; i <= ed;++i)
{
vector<TreeNode*> leftList = help(st,i-1);
vector<TreeNode*> rightList = help(i+1,ed);
for(TreeNode* left : leftList)
{
for(TreeNode* right:rightList)
{
TreeNode* root = new TreeNode(i);
root->left = left;
root->right = right;
res.push_back(root);
}
}
}
return res;
}
vector<TreeNode*> generateTrees(int n)
{
if(n == 0) return {};
return help(1,n);
}
vector<int>maxSlidingWindow(const vector<int>& nums,int k)
{
int n = nums.size();
deque<int>q;
vector<int>res(n-k+1);
for(int i = 0; i < n; ++i)
{
int start = i-k+1;
while(!q.empty() && i - q.front() >= k)q.pop_front();
while(!q.empty() && nums[q.front()] <= nums[i])q.pop_back();
q.push_back(i);
if(start >= 0)res[start] = nums[q.front()];
}
return res;
}
void flatten(TreeNode* node)
{
if(nullptr == node)return;
if(node->left)flatten(node->left);
if(node->right)flatten(node->right);
TreeNode* right = node->right;
node->right = node->left;
node->left = nullptr;
while(node->right)node = node->right;
node->right = right;
}
void faltten1(TreeNode* root)
{
if(nullptr == root)return;
TreeNode* tmpRoot = root;
while(tmpRoot)
{
if(tmpRoot->left)
{
TreeNode* tmp = tmpRoot->left;
while(tmp && tmp->right)tmp = tmp->right;
tmp->right = tmpRoot->right;
tmpRoot->right = tmpRoot->left;
tmpRoot->left = nullptr;
}
tmpRoot = tmpRoot->right;
}
}
int lengthofLongestSubString(string s)
{
int n = s.size(),left = -1, res = 0;
unordered_set<char>set;
for(int i = 0; i < n ; ++i)
{
if(i != 0)
{
set.erase(s[i-1]);
}
while(left+1 < n && !set.count(s[left+1]))
{
set.insert(s[left+1]);
++left;
}
res = max(res,left - i + 1);
}
return res;
}
int maxProfit_cold(vector<int>prices)
{
if(prices.empty())return 0;
int n = prices.size();
if(n < 2)return 0;
vector<vector<int>>dp(n,vector<int>(2));
dp[0][0] = 0;
dp[0][1] = -prices[0];
dp[1][0] = max(dp[0][0],dp[0][1] + prices[1]);
dp[1][1] = max(dp[0][1],dp[0][0] - prices[1]);
for(int i = 2; i < n; ++i)
{
dp[i][1] = max(dp[i-1][1],dp[i-2][0]-prices[i]);
dp[i][0] = max(dp[i-1][0],dp[i-1][1]+prices[i]);
}
return dp[n-1][0];
}
int singleNumberI(vector<int>& nums)
{
vector<int>bits(32,0);
for(int i = 0; i < nums.size(); ++i)
{
for(int j = 0; j < 32; ++j)
{
if(nums[i] &(1 << j))
++bits[j];
}
}
int res = 0;
for(int i = 0; i < bits.size(); ++i)
{
if(bits[i]%3 == 1)
{
res += (1 << i);
}
}
return res;
}
vector<int> findAnagrams(string s, string p)
{
vector<int>res;
if(s.size() < p.size())return res;
int plen = p.size();
unordered_map<char,int>m;
string str = "abcdefghijklmnopqrstuvwxyz";
for(auto ch:str)m[ch] = 0;
unordered_map<char,int>tmp(m);
for(auto x:p)++m[x];
for(int i = 0; i < s.size(); ++i)
{
if(i >= plen)--tmp[s[i-plen]];
++tmp[s[i]];
if(tmp==m)res.push_back(i-plen+1);
}
return res;
}
bool canJump(const vector<int>& nums)
{
if(nums.size() == 1)return true;
int cover = 0;
for(int i = 0; i < nums.size(); ++i)
{
cover = max(i + nums[i],cover);
if(cover >= nums.size() - 1)return true;
}
return false;
}
int uniquePathsI(int m, int n)
{
vector<int>dp(n,1);
for(int i = 1; i < m; ++i)
{
for(int j = 1; j < n; ++j)
{
dp[j] = dp[j] + dp[j-1];
}
}
return dp[n-1];
}
int findUnsortedSubarray(vector<int>& nums)
{
if(nums.empty())return 0;
int n = nums.size();
int st = -1, ed = -2;
int maxVal = nums[0],minVal=nums[n-1];
for(int i = 0; i < n; ++i)
{
int j = n - 1 - i;
maxVal =max(maxVal,nums[i]);
minVal = min(minVal,nums[j]);
if(nums[i] < maxVal)ed = i;
if(nums[j] > minVal)st = j;
}
return ed - st + 1;
}
int uniquePaths(int m, int n)
{
vector<vector<int>>dp(m,vector<int>(n));
for(int i = 0;i < m; ++i)
{
dp[i][0] = 1;
}
for(int i = 0; i < n; ++i)
{
dp[0][i] = 1;
}
for(int i = 1; i < m; ++i)
{
for(int j = 1; j < n ; ++j)
{
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m-1][n-1];
}
int searchInsert(vector<int>& nums, int target){
int left=0;
int numsSize = nums.size();
int right=numsSize-1;
if(nums[right] < target)
return numsSize;
if(nums[right] == target)
return right;
if(nums[left] >= target)
return left;
while(nums[left]<target && nums[right]>target)
{
int mid = left + (right - left) / 2;
if(mid==left)
{
return right;
}
if(nums[mid]>target)
{
right=mid;
}
if(nums[mid]<target)
{
left=mid;
}
if(nums[mid]==target)
{
return mid;
}
}
if(nums[left]<target)
{
return right;
}
if(nums[right]>target)
{
return left;
}
//最后不要忘记返回噢
return 0;
}
void print(LinkNode* node)
{
while(node != nullptr)
{
cout << node->val <<" ";
node = node->next;
}
cout << endl;
}
LinkNode* reverseII(LinkNode* head)
{
LinkNode* pre = nullptr;
while(head != nullptr)
{
LinkNode* next = head->next;
head->next = pre;
pre = head;
head = next;
}
return pre;
}
LinkNode* swapPairs(LinkNode* head) {
if (nullptr == head || nullptr == head->next)return head;
LinkNode* dummy = new LinkNode(0);
dummy->next = head;
LinkNode* temp = dummy;
while(nullptr != temp->next && nullptr != temp->next->next)
{
LinkNode* p = temp->next;
LinkNode* q = temp->next->next;
temp->next = q;
p->next = q->next;
q->next = p;
temp = p;
}
return dummy->next;
}
LinkNode* reverseIII(LinkNode* head)
{
LinkNode* pre = nullptr;
while(head != nullptr)
{
LinkNode* next = head->next;
head->next = pre;
pre = head;
head = next;
}
return pre;
}
LinkNode* reverse(LinkNode* head,LinkNode* newHead)
{
if(nullptr == head)return newHead;
LinkNode* next = head->next;
head->next = newHead;
return reverse(next,head);
}
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if(matrix.empty() || matrix[0].empty())return false;
int row = matrix.size() - 1,col = 0;
while(row >= 0 && col < matrix[0].size())
{
if(matrix[row][col] > target) --row;
else if(matrix[row][col] < target) ++col;
else return true;
}
return false;
}
LinkNode* mergeTwoLists(LinkNode* l1, LinkNode* l2)
{
LinkNode* dummy = new LinkNode(0);
LinkNode* cur = dummy;
while(nullptr != l1 && nullptr != l2)
{
if(l1->val < l2->val)
{
cur->next = new LinkNode(l1->val);
l1 = l1->next;
}
else
{
cur->next = new LinkNode(l2->val);
l2 = l2->next;
}
cur = cur->next;
}
cur->next = l1 == nullptr ? l2:l1;
return dummy->next;
}
int climbStairs(int n)
{
if(n <= 2)return n;
vector<int>dp(n+1);
dp[1] = 1;
dp[2] = 2;
for(int i = 3; i <= n; ++i)
{
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
void reverse(vector<int>& nums, int start, int end) {
while(start < end)
{
int tmp = nums[start];
nums[start] = nums[end];
nums[end] = tmp;
++start;
--end;
}
}
void inorder(TreeNode* root)
{
if(root == nullptr)return;
inorder(root->left);
cout << root->val << endl;
inorder(root->right);
}
void inorder(TreeNode* root, vector<int>&res)
{
stack<TreeNode*>st;
while(root != nullptr || !st.empty())
{
while(root != nullptr)
{
st.push(root);
root = root->left;
}
root = st.top();
st.pop();
res.push_back(root->val);
root = root->right;
}
}
void rotate(vector<int>& nums,int k)
{
k %= nums.size();
reverse(nums,0,nums.size() - 1);
reverse(nums,0,k-1);
reverse(nums,k,nums.size() - 1);
}
string letterMap[10]={
"",
"",
"abc",
"def",
"ghi",
"jkl",
"mno",
"pqrs",
"tuv",
"wxyz"};
void backtrack(const string & digits, string& s, vector<string>& res,int index)
{
if(s.size() == digits.size())
{
res.push_back(s);
return;
}
int digit = digits[index] - '0';
string letter = letterMap[digit];
for(int i = 0; i < letter.size(); ++i)
{
s.push_back(letter[i]);
backtrack(digits,s,res,index + 1);
s.pop_back();
}
}
vector<string> letterCombinations(const string& digits)
{
vector<string>res;
if(digits.size() == 0)return res;
string s;
backtrack(digits,s,res,0);
return res;
}
int climbStairs_m(int n,int m)
{
vector<int>dp(n+1,0);
dp[0] = 1;
for(int i = 1; i <= n; ++i)
{
for(int j = 1;j <= m; ++j)
{
if(i - j >= 0)dp[i]+=dp[i-j];
}
}
return dp[n];
}
int lengthOfList(const vector<int>& nums)
{
int n = nums.size();
if(n <= 1)return n;
vector<int>dp(n,1);
for(int i = 1; i < n ; ++i)
{
for(int j = 0; j < i; ++j)
{
if(nums[i] > nums[j])dp[i] = max(dp[i],1 + dp[j]);
}
}
return *max_element(dp.begin(),dp.end());
}
int maxProfit(const vector<int>& prices)
{
int n = prices.size();
if(0 == n)return 0;
vector<vector<int>>dp(n,vector<int>(2,0));
dp[0][0] = 0;
dp[0][1] = -prices[0];
for(int i = 1; i < prices.size(); ++i)
{
dp[i][0] = max(dp[i-1][1] + prices[i],dp[i-1][0]);
dp[i][1] = max(dp[i-1][1],-prices[i]);
}
return dp[n-1][0];
}
int getleftposition(vector<int>& nums,int target)
{
int left = 0, right = nums.size() - 1;
while(left <= right)
{
int mid = left + ((right - left )>> 1);
if(target > nums[mid])left = mid + 1;
else if(target < nums[mid])right = mid - 1;
else right = mid - 1;
}
if(left == nums.size() || nums[left] != target)
return -1;
return left;
}
vector<int> countBits(int num) {
vector<int> res(num+1);
for(int i=1;i<=num;++i)
res[i] = (i%2) ? (res[i/2]+1) : res[i/2];
return res;
}
int getrightposition(vector<int>&nums,int target)
{
int left = 0,right = nums.size() - 1;
while(left <= right)
{
int mid = left + ((right - left) >> 1);
if(target < nums[mid])right = mid - 1;
else if(target == nums[mid])left = mid + 1;
else left = mid + 1;
}
if(right == -1 || nums[right]!=target)return -1;
return right;
}
int findKthLargest_q(vector<int>& nums,int k)
{
int n = nums.size();
int l = 0,r = n - 1;
while(true)
{
int i = l,j = r;
int randPos = rand()%(r-l+1) +l;
swap(nums[l],nums[randPos]);
int base = nums[l];
while(i < j)
{
while(i < j && nums[j]<=base)--j;
while(i < j && nums[i]>=base)++i;
if(i<j)swap(nums[i],nums[j]);
}
swap(nums[l],nums[i]);
if(i == k - 1)return nums[i];
else if(i > k - 1) r = i - 1;
else l = i + 1;
}
return -1;
}
int findKthLargest(vector<int>& nums,int k)
{
int n = nums.size();
for(int i = n / 2 -1 ;i >= 0; --i)
heapify(nums,n,i);
for(int i = nums.size()-1;i >=nums.size()-k+1;--i)
{
swap(nums[0],nums[i]);
--n;
heapify(nums,n,0);
}
return nums[0];
}
vector<int> searchRange(vector<int>& nums, int target) {
vector<int>ans(2,-1);
ans[0] = getleftposition(nums,target);
ans[1] = getrightposition(nums,target);
return ans;
}
int coinChange(const vector<int>&nums,int amount)
{
vector<int>dp(amount + 1,INT_MAX);
dp[0] = 0;
for(int i = 0; i < nums.size(); ++i)
{
for(int j = nums[i];j <= amount; ++j)
{
if(dp[j - nums[i]]!= INT_MAX)
{
dp[j] = min(dp[j],dp[j-nums[i]] + 1);
}
}
}
if(dp[amount] == INT_MAX)return -1;
return dp[amount];
}
int V = 0;
TreeNode* convertBST(TreeNode* root)
{
if(nullptr == root)return root;
root->right = convertBST(root->right);
root->val += V ;
V = root->val;
root->left = convertBST(root->left);
return root;
}
void nextPermutation(vector<int>& nums)
{
int i = nums.size() - 2;
while(i >= 0 && nums[i] >= nums[i+1])
{
--i;
}
if(i >= 0)
{
int j = nums.size() - 1;
while(i < j && nums[i] >= nums[j])
--j;
int tmp = nums[j];
nums[j] = nums[i];
nums[i] = tmp;
}
int end = nums.size() - 1;
int start = i + 1;
while(start < end)
{
int tmp = nums[end];
nums[end] = nums[start];
nums[start] = tmp;
--end;
++start;
}
return;
}
// int minEditDistance(string s, string t)
// {
// int m = s.size(), n = t.size();
// vector<vector<int>>dp(m+1,vector<int>(n+1,0));
// for(int i = 0; i < m; ++i)dp[i][0] = i;
// for(int j = 0; j < n; ++j)dp[0][j] = j;
// for(int i = 1; i <= m; ++i)
// {
// for(int j = 1; j <= n; ++j)
// {
// if(s[i-1] == t[j-1])
// {
// dp[i][j] = dp[i-1][j-1];
// }
// else{
// dp[i][j] = min({dp[i-1][j-1],dp[i][j-1],dp[i-1][j]}) + 1;
// }
// }
// }
// return dp[m][n];
// }
int jump(const vector<int>& nums)
{
int step = 0,maxReach = 0,end = 0;
for(int i = 0; i < nums.size(); ++i)
{
maxReach = max(maxReach,nums[i] + i);
if(i == end)
{
++step;
end = maxReach;
}
}
return step;
}
bool wordBreak(string s, const vector<string>& wordDict)
{
vector<bool>dp(s.size() + 1, false);
unordered_set<string>set(wordDict.begin(),wordDict.end());
dp[0] = true;
for(int i = 1; i <= s.size(); ++i)
{
for(int j = 0; j < i; ++j)
{
string word = s.substr(j,i - j);
if(set.find(word)!= set.end()&&dp[j])
{
dp[i] = true;
}
}
}
return dp[s.size()];
}
int minEditDistance(string s1,string s2)
{
int m = s1.size(),n = s2.size();
vector<vector<int>>dp(m+1,vector<int>(n+1,0));
for(int i = 0; i < m ;++i)
{
dp[i][0] = i;
}
for(int j = 0; j < n; ++j)
{
dp[0][j] = j;
}
for(int i = 1; i <= m; ++i)
{
for(int j =1; j <= n; ++j)
{
if(s1[i-1] == s2[j-1])
{
dp[i][j]=dp[i-1][j-1];
}
else
{
dp[i][j] = min({dp[i-1][j-1],dp[i-1][j],dp[i][j-1]} ) + 1;
}
}
}
return dp[m][n];
}
string longestCommonPrefix(vector<string>& strs) {
string res = "";
if(strs.size() == 0)return res;
sort(strs.begin(),strs.end());
for(int i = 0; i < strs[0].size();++i)
{
char tmp = strs[0][i];
int j = 1 ;
for(j = 1; j < strs.size();++j)
{
if(tmp != strs[j][i])break;
}
if(j >= strs.size())res += tmp;
else break;
}
return res;
}
int rob(const vector<int>& nums)
{
int n = nums.size();
if(n == 0)return 0;
if(n ==1) return nums[0];
vector<int>dp(n,INT_MIN);
dp[0] = nums[0];
dp[1] = max(nums[0],nums[1]);
for(int i = 2; i < n; ++i)
{
dp[i] = max(dp[i-1],dp[i-2]+nums[i]);
}
return dp[n-1];
}
LinkNode* endOfFirst(LinkNode* head)
{
LinkNode* slow = head;
LinkNode* fast = head;
while(fast->next != nullptr && fast->next->next != nullptr)
{
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
LinkNode* reverse(LinkNode* head)
{
LinkNode* pre = nullptr;
while(head != nullptr)
{
LinkNode* next = head->next;
head->next = pre;
pre = head;
head = next;
}
return pre;
}
bool isPalindrome(LinkNode* head)
{
LinkNode* firstHead = endOfFirst(head);
LinkNode* second = reverse(firstHead->next);
LinkNode* p1 = head;
LinkNode* p2 = second;
bool result = true;
while(result && p2 != nullptr)
{
if(p1->val != p2->val)return false;
p1 = p1->next;
p2 = p2->next;
}
firstHead->next = reverse(second);
return result;
}
bool isPalindrome(int x)
{
if(x < 0 || (x > 0 && (x % 10) == 0))return false;
int reverse = 0;
while(x > reverse)
{
reverse = reverse * 10 + x % 10;
x /= 10;
}
return (x == reverse || x == reverse / 10);
}
int largestRectangle(vector<int>& height)
{
stack<int>st;
int res = 0;
for(int i = 0; i < height.size(); ++i)
{
while(!st.empty() && height[i] <= height[st.top()])
{
int preHeight = height[st.top()];
st.pop();
int width = i - (st.empty() ? 0:st.top() + 1);
res = max(res,preHeight * width);
}
st.push(i);
}
while(!st.empty())
{
int preHeight = height[st.top()];
st.pop();
int width = height.size() - (st.empty() ? 0 :st.top() + 1);
res = max(res,preHeight * width);
}
return res;
}
int maxRectangle(const vector<vector<string>>& matrix)
{
int m = matrix.size();
if(m == 0)return 0;
int n = matrix[0].size();
vector<int>height(n);
int res = 0;
for(int i = 0; i < m; ++i)
{
for(int j = 0;j < n; ++j)
{
if(matrix[i][j] == "0")height[j]=0;
else ++height[j];
}
res = max(res,largestRectangle(height));
}
return res;
}
int longestValidParentheses(string s) {
int res = 0;
stack<int>st;
st.push(-1);
for(int i = 0;i < s.size(); ++i)
{
char c =s[i];
if(c == '(')
{
st.push(i);
}
else
{
st.pop();
if(st.empty())st.push(i);
else
res = max(res, i - st.top());
}
}
return res;
}
bool canFinish(int numCourses,vector<vector<int>>& prerequisites)
{
vector<int>degree(numCourses,0);
vector<list<int>>G(numCourses,list<int>({}));
for(auto p:prerequisites)
{
++degree[p[0]];
G[p[1]].push_back(p[0]);
}
queue<int>q;
for(int i = 0; i < numCourses;++i)
{
if(0 == degree[i])q.push(i);
}
while(!q.empty())
{
int u=q.front();
q.pop();
degree[u] = 0;
for(auto v:G[u])
{
--degree[v];
if(0 == degree[v])
{
q.push(v);
}
}
}
for(int i = 0;i < numCourses; ++i){
if(degree[i]!= 0)
return false;
}
return true;
}
// LinkNode* removeNthFromEnd(LinkNode* head,int n)
// {
// LinkNode dummy(0);
// dummy.next = head;
// LinkNode* first = &dummy, *second = &dummy;
// for(int i = 1; i <= n + 1; ++i)
// {
// first = first->next;
// }
// while(first != nullptr)
// {
// first = first->next;
// second = second->next;
// }
// second->next = second->next->next;
// return dummy.next;
// }
LinkNode* reverseKGroup(LinkNode* head, int k)
{
LinkNode* node = head;
int cnt = 0;
while(cnt < k)
{
if(nullptr == node)return head;
node = node->next;
++cnt;
}
LinkNode* pre = reverseKGroup(node,k);
while(cnt-- > 0)
{
LinkNode* next = head->next;
head->next = pre;
pre = head;
head = next;
}
return pre;
}
LinkNode* removeNthFromEnd(LinkNode* head, int n)
{
LinkNode* dummy = new LinkNode(0);
dummy->next = head;
LinkNode* first = dummy, *second = dummy;
for(int i = 1; i <= n + 1; ++i)
{
first = first->next;
}
while(first != nullptr)
{
first = first->next;
second = second->next;
}
second->next = second->next->next;
return dummy->next;
}
int search(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while(left <= right)
{
int mid = left + (right - left) / 2;
if(nums[mid]==target)return mid;
else if(nums[left] <= nums[mid])
{
if(nums[left] <= target && nums[mid] >= target)right = mid -1;
else left = mid + 1;
}
else
{
if(nums[mid] <= target && nums[right] >= target)left = mid + 1;
else right = mid - 1;
}
}
return -1;
}
bool isContain(const vector<int>& nums,int val)
{
for(auto &num : nums)
{
if(num == val)return true;
}
return false;
}
void help(vector<int>& nums,vector<vector<int>>&res,vector<int>&tmp,int index)
{
if(tmp.size() == nums.size())res.emplace_back(tmp);
else
{
for(int i = 0; i < nums.size(); ++i)
{
if(isContain(tmp,nums[i]))continue;
tmp.emplace_back(nums[i]);
help(nums,res,tmp,index + 1);
tmp.pop_back();
}
}
}
int majorNum(const vector<int>& nums)
{
int major = 0,res = 0;
unordered_map<int,int>m;
for(auto & num:nums)
{
++m[num];
if(m[num] > major)
{
major = m[num];
res = num;
}
}
return res;
}
vector<vector<int>>permute(vector<int>& nums)
{
vector<vector<int>>res;
vector<int>tmp;
sort(nums.begin(),nums.end());
help(nums,res,tmp,0);
return res;
}
void print(const vector<vector<int>>& nums)
{
for(auto && num : nums)
{
for(auto && n : num)
{
cout << n << " ";
}
cout << endl;
}
}
bool compare(TreeNode* left, TreeNode* right)
{
if(nullptr == left && nullptr != right)return false;
else if(nullptr == right && nullptr != left)return false;
else if(nullptr == left && nullptr == right)return true;
else if(left->val != right->val)return false;
bool outside = compare(left->left,right->right);
bool inside = compare(left->right,right->left);
return inside && outside;
}
bool isSymmetric(TreeNode* root)
{
if(root == nullptr)return true;
return compare(root->left,root->right);
}
bool isSymmetric_stack(TreeNode* root)
{
if(nullptr == root)return true;
stack<TreeNode*>st;
st.push(root->left);
st.push(root->right);
while(!st.empty())
{
TreeNode* leftNode = st.top();st.pop();
TreeNode* rightNode = st.top();st.pop();
if(!leftNode && !rightNode)continue;
if(!leftNode || !rightNode || leftNode->val != rightNode->val)return false;
st.push(leftNode->left);
st.push(rightNode->right);
st.push(leftNode->right);
st.push(rightNode->left);
}
return true;
}
bool isSymmetric_queue(TreeNode* root)
{
if(root == nullptr)return true;
queue<TreeNode*>q;
q.push(root->left);
q.push(root->right);
while(!q.empty())
{
TreeNode* leftNode = q.front();q.pop();
TreeNode* rightNode = q.front();q.pop();
if(!leftNode && !rightNode)continue;
if(!leftNode || !rightNode || (leftNode->val != rightNode->val))
return false;
q.push(leftNode->left);
q.push(rightNode->right);
q.push(leftNode->right);
q.push(rightNode->left);
}
return true;
}
int largestRectangleArea(const vector<int>& nums)
{
stack<int>st;
int n = nums.size();
int res = 0;
for(int i = 0; i < n; ++i)
{
while(!st.empty() && nums[i] <= nums[st.top()])
{
int pre = st.top();
st.pop();
int preHeight = nums[pre];
int width = i - (st.empty() ? 0 :st.top() + 1);
res = max(res, preHeight * width);
}
st.push(i);
}
while(!st.empty())
{
int preHieght = nums[st.top()];
st.pop();
int width = n - (st.empty() ? 0 : st.top() + 1);
res = max(res,preHieght * width);
}
return res;
}
LinkNode* partition(const vector<LinkNode*>& lists,int start, int end)
{
if(start == end)return lists[start];
if(start < end)
{
int mid = start + (end - start) / 2;
auto l1 = partition(lists,start,mid);
auto l2 = partition(lists,mid+1,end);
return mergeTwoLists(l1,l2);
}
return nullptr;
}
LinkNode* mergeKLists(vector<vector<int>>& lists)
{
vector<LinkNode*>listss;
for(int i = 0; i < lists.size(); ++i)
{
listss.push_back(generateLinkNode(lists[i]));
}
return partition(listss,0,lists.size() - 1);
}
void twoSum(const vector<int>& nums,int left,int right,int target,vector<vector<int>>&res)
{
while(left < right)
{
int tmp = nums[left] + nums[right] + target;
if(0 == tmp)
{
res.push_back({target,nums[left++],nums[right--]});
while(left < right && nums[left] == nums[left-1])++left;
while(left < right && nums[right] == nums[right+1])--right;
}
else if(tmp>0)--right;
else ++left;
}
return;
}
vector<vector<int>>ThreeSum(vector<int>& nums)
{
sort(nums.begin(),nums.end());
vector<vector<int>>res;
for(int i = 0; i < nums.size() - 2; ++i)
{
if(i != 0 && nums[i] == nums[i-1])continue;
int left = i + 1, right = nums.size() -1;
twoSum(nums,left,right,nums[i],res);
}
return res;
}
void twoSumI(const vector<int>& nums,int left,int right,int target,vector<vector<int>>&res)
{
while(left < right)
{
int tmp = nums[left] +nums[right] + target;
if(0 == tmp)
{
res.push_back({target,nums[left++],nums[right--]});
while(left < right && nums[left] == nums[left - 1])++left;
while(left < right && nums[right] == nums[right + 1])--right;
}
else if(0 < tmp)--right;
else ++left;
}
return;
}
int subSet(const vector<int>& nums, int S)
{
int n = nums.size();
vector<vector<int>>dp(n+1,vector<int>(S+1));
dp[0][0] = 1;
for(int i = 1; i <= n; ++i)
{
for(int j = 0; j <= S; ++j)
{
dp[i][j] = dp[i - 1][j];
if(j - nums[i-1] >= 0)dp[i][j]+=dp[i-1][j-nums[i-1]];
}
}
return dp[n][S];
}
int findTargetSumWays(const vector<int>& nums, int S)
{
int sum = accumulate(nums.begin(),nums.end(),0);
if(S > sum || (S + sum) % 2 == 1) return 0;
return subSet(nums,(sum + S) / 2);
}
vector<vector<int>>ThreeSum2(vector<int>&nums)
{
sort(nums.begin(),nums.end());
vector<vector<int>>res;
for(int i = 0 ; i < nums.size() - 2; ++i)
{
if(i!=0 && nums[i] == nums[i-1])continue;
int left = i + 1, right = nums.size() - 1;
twoSumI(nums,left,right,nums[i],res);
}
return res;
}
int maxSubArray(const vector<int>& nums)
{
int res = INT_MIN,sum = 0, n = nums.size();
for(int i = 0; i < n; ++i)
{
sum += nums[i];
res = max(res,sum);
if(sum < 0) sum = 0;
}
return res;
}
int maxSubArray0(const vector<int>& nums)
{
int maxSum = INT_MIN,maxEnd = 0, n = nums.size();
for(int i = 0; i < n; ++i)
{
maxEnd += nums[i];
maxSum = max(maxSum,maxEnd);
if(maxEnd < 0) maxEnd = 0;
}
return maxSum;
}
int findDuplicate(const vector<int>&nums)
{
int slow = nums[0],fast = nums[nums[0]];
while(slow != fast)
{
slow = nums[slow];
fast = nums[nums[fast]];
}
int p1 = nums[0];
int p2 = nums[slow];
while(p1 != p2)
{
p1 = nums[p1];
p2 = nums[p2];
}
return p1;
}
int length(LinkNode* head)
{
int size = 0;
while(head != nullptr)
{
++size;
head = head->next;
}
return size;
}
LinkNode* getInersection(LinkNode* headA, LinkNode* headB)
{
int lenA = length(headA), lenB = length(headB);
while(lenB > lenA)
{
headB = headB->next;
--lenB;
}
while(lenA > lenB)
{
headA = headA->next;
--lenA;
}
while(headA != nullptr&& headB != nullptr)
{
if(headA->val == headB->val)return headA;
headA = headA->next;
headB = headB->next;
}
return nullptr;
}
string minWindow(string s, string t)
{
unordered_map<char,int>map;
for(char c:t)
{
++map[c];
}
int left = 0, minStart = 0, minLen = INT_MAX, cnt = 0;
for(int i = 0; i < s.size(); ++i)
{
char c = s[i];
if(map.count(c))
{
if(map[c]>0)++cnt;
--map[c];
}
while(cnt == t.size())
{
if(i - left + 1 < minLen)
{
minLen = i - left + 1;
minStart = left;
}
char leftChar = s[left];
if(map.count(leftChar))
{
++map[leftChar];
if(map[leftChar] > 0) --cnt;
}
++left;
}
}
if(minLen == INT_MAX)return "";
return s.substr(minStart,minLen);
}
void dfs(vector<vector<int>>& res,const vector<int>&nums,vector<int>&tmp,int start)
{
res.emplace_back(tmp);
for(int i = start; i < nums.size(); ++i)
{
tmp.emplace_back(nums[i]);
dfs(res,nums,tmp,i + 1);
tmp.pop_back();
}
return ;
}
vector<vector<int>>subset(const vector<int>& nums)
{
vector<vector<int>>res;
vector<int>tmp;
dfs(res,nums,tmp,0);
return res;
}
int numTrees(int n)
{
vector<int>G(n+1);
G[0] = 1;
G[1] = 1;
for(int i = 2; i <= n; ++i)
{
for(int j = 1; j <= i; ++j)
{
G[i] += G[j-1]*G[i-j];
}
}
return G[n];
}
LinkNode* sortList(LinkNode* head)
{
if(nullptr == head || nullptr == head->next)
return head;
LinkNode* lowHead = new LinkNode(0);
LinkNode* low = lowHead;
LinkNode* midHead = new LinkNode(0);
LinkNode* mid = midHead;
LinkNode* highHead = new LinkNode(0);
LinkNode* high = highHead;
int val = head->val;
LinkNode* node = head;
while(nullptr != node)
{
if(node->val > val)
{
high->next = node;
high = high->next;
}
else if(node->val < val)
{
low->next = node;
low = low->next;
}
else{
mid->next = node;
mid = mid->next;
}
node = node->next;
}
low->next = nullptr;
high->next = nullptr;
lowHead->next = sortList(lowHead->next);
highHead->next = sortList(highHead->next);
low = lowHead;
while(nullptr != low->next)
{
low = low->next;
}
low->next = midHead->next;
mid->next = highHead->next;
return lowHead->next;
}
int maxProduct(const vector<int>& nums)
{
int n = nums.size();
vector<int>maxVal(n), minVal(n);
int res = nums[0];
maxVal[0] = nums[0], minVal[0] = nums[0];
for(int i = 1; i < n; ++i)
{
if(nums[i]>0)
{
maxVal[i] = max(maxVal[i - 1] * nums[i],nums[i]);
minVal[i] = min(minVal[i-1] * nums[i],nums[i]);
}
else
{
maxVal[i] = max(minVal[i - 1] * nums[i],nums[i]);
minVal[i] = min(maxVal[i-1] * nums[i],nums[i]);
}
res = max(res,maxVal[i]);
}
return res;
}
TreeNode* lowestCommonTree(TreeNode* node,TreeNode* p, TreeNode* q)
{
if(node == nullptr || node == p || node == q)return node;
TreeNode* left = lowestCommonTree(node->left,p,q);
TreeNode* right = lowestCommonTree(node->right,p,q);
if(left != nullptr && right != nullptr)return node;
else if(left != nullptr && right == nullptr)return left;
else if(left == nullptr && right != nullptr )return right;
else return nullptr;
}
int firstMissingPositive(vector<int>& nums) {
int n = nums.size();
for(int i = 0; i < n; ++i)
{
while(nums[i] > 0 && nums[i] <= n && nums[i] != nums[nums[i]-1])
{
swap(nums[i],nums[nums[i]-1]);
}
for(int i = 0; i < n; ++i)
{
if(nums[i] != i + 1)
{
return i + 1;
}
}
return n + 1;
}
}
int numSquares(int n)
{
vector<int>dp(n+1,INT_MAX);
dp[0] = 0;
for(int i = 0; i <= n; ++i)
{
for(int j = 1; j * j <= i; ++j)
{
dp[i] = min(dp[i],dp[i - j * j]+1);
}
}
return dp[n];
}
vector<int>twoSum(const vector<int>& nums, int target)
{
unordered_map<int, int>map;
for (int i = 0; i < nums.size(); ++i)
{
int diff = target - nums[i];
if (map.find(diff) != map.end())
{
return { map.at(diff),i };
}
map[nums[i]] = i;
}
return { -1,-1 };
}
int main()
{
vector<int> nums{10,1,3,3,2,4,5};
print(qs(nums));
print(hpS(nums));
//LeetCode15
vector<int>nums2{ -1,0,1,2,-1,-4 };
print(ThreeSum2(nums2));
// LeetCode53
nums = {-2,1,-3,4,-1,2,1,-5,4};
cout << maxSubArray0(nums) << endl;
// LeetCode7
cout << reverse1(-123) << endl;
//LeetCode11
vector<int>height{4,2,0,3,2,5};
cout << trapI(height) << endl;
//LeetCode42
height = {4,2,0,3,2,5};
cout << rain(height) << endl;
cout << rainI(height) << endl;
//LeetCode20
string s1 = "{[]}";
cout << isValid1(s1) << endl;
//LeetCode10
string s = "aab";
string p = "c*a*b";
cout << isMatch(s,p) << endl;
//LeetCode26
nums = {1,2,3,4,4,5,6,6,6};
removeDuplicatesI(nums);
for(auto & num:nums)
{
cout << num <<" ";
}
cout << endl;
//LeetCode136
nums = {1,2,2,3,3};
cout << singleNum0(nums) << endl;
//LeetCode22
int n = 3;
print(gen(n));
nums = {1,1,1,3,3,3,4};
cout << singleNumberI(nums) <<endl;
//LeetCode206
nums = {1,2,3,4,5};
print(reverseIII(generateLinkNode(nums)));
print(reverse(generateLinkNode(nums),nullptr));
// //LeetCode21
vector<int>l1 = {1,2,4};
vector<int>l2 = {1,3,4};
print(mergeTwoLists(generateLinkNode(l1),generateLinkNode(l2)));
// //LeetCode70 爬楼梯
cout << climbStairs(3) << endl;
cout << climbStairs_m(3,2) << endl;//变体为完全背包问题
// //LeetCode300 递增最长子序列
nums = {0,1,0,3,2,3};
cout << lengthOfList(nums) << endl;
// //LeetCode121 买卖股票的最佳时机
nums = {7,1,5,3,6,4};
cout << maxProfit(nums) << endl;
// //LeetCode72 编辑距离
string s0 = "intention";
s1 = "execution";
cout << minEditDistance(s0,s1) << endl;
// //LeetCode14 最长公共前缀
vector<string>ss{"fly","flower","flsdf"};
cout << longestCommonPrefix(ss) << endl;
// //打家劫舍
// //LeetCode198 打家劫舍
nums = {2,7,9,3,1};
cout << rob(nums) << endl;
// //LeetCode9
int x = 0121;
cout << isPalindrome(x) << endl;
// //LeetCode19
nums = {1,2,3,4,5};
n = 2;
LinkNode* node = generateLinkNode(nums);
print(node);
print(removeNthFromEnd(node,n));
// //LeetCode33搜索旋转排序数组。
nums={4,5,6,7,0,1,2};
cout << search(nums,0) << endl;
// // LeetCode46
nums = {1,2,3};
print(permute(nums));
// //LeetCode101
//LeetCode101对称二叉树
TreeNode n0(1);
TreeNode n1(2);
TreeNode n2(2);
TreeNode n3(3);
TreeNode n4(4);
TreeNode n5(3);
TreeNode n6(4);
n0.left = &n1;
n0.right = &n2;
n1.left = &n3;
n1.right = &n4;
n2.left = &n6;
n2.right = &n5;
cout << isSymmetric(&n0) << endl;
cout << isSymmetric_stack(&n0) << endl;
cout << isSymmetric_queue(&n0) << endl;
// //LeetCode84
height = {2,1,5,6,2,3};
cout << largestRectangleArea(height) << endl;
// //LeetCode39 组合总和(可重复)
vector<int>candidates{2,3,6,7};
int target = 7;
print(combinationSum(candidates,target));
// //LeetCode13罗马数字转整数
s = "MCMXCIV";
cout << romanToInt(s) << endl;
// //LeetCode23合并k个链表
vector<vector<int>> lists = {{1,4,5},{1,3,4},{2,6}};
print(mergeKLists(lists));
// //LeetCode17 电话号码的字母组合
print(letterCombinations("23"));
// //LeetCode322 零钱兑换
vector<int>coins = {1,2,5};
int amount = 11;
cout << coinChange(coins,amount) << endl;
// //LeetCode32
string s4 = ")()())";
cout << longestValidParentheses(s4) << endl;
// // LeetCode287
nums = {1,3,4,2,2};
cout << findDuplicate(nums) << endl;
//LeetCode122
vector<int>prices{1,2,3,4,5};
prices = {7,1,5,3,6,4};
cout << maxProfit_II(prices) <<endl;
cout << maxProfit_II_greedy(prices) << endl;
//LeetCode160
vector<int>listA{4,1,8,4,5};
vector<int>listB{5,6,1,8,4,5};
cout << getInersection(generateLinkNode(listA),generateLinkNode(listB))->val << endl;
//LeetCde55 跳跃游戏
nums = {2,3,1,1,4};
cout << canJump(nums) << endl;
//LeetCode76
s = "ADOBECODEBANC";
string t = "ABC";
cout << minWindow(s,t) << endl;
// LeetCode200
vector<vector<string>>grid{{"1","1","0","1","1"},{"1","0","1","0","1"},{"1","0","0","0","1"}};
cout << numIslands(grid)<<endl;
//LeetCode78
nums = {1,2,3};
print(subset(nums));
//LeetCode31
nums = {1,5,1};
nextPermutation(nums);
print(nums);
//LeetCode96
cout << numTrees(3) << endl;
//LeetCode148
nums = {4,2,1,3};
node = generateLinkNode(nums);
node = sortList(node);
print(node);
//LeetCode501 二叉搜索树中的众数
cout << "=====" << endl;
TreeNode t10(1);
TreeNode t11(2);
TreeNode t12(2);
t10.left = &t11;
t10.right = &t12;
//LeetCode236 二叉树的公共祖先
cout << lowestCommonTree(&t10,&t11,&t12)->val << endl;
//LeetCode25
nums = {1,2,3,4,5};
int k = 2;
print(reverseKGroup(generateLinkNode(nums),k));
//LeetCode6
s = "LEETCODEISHIRING";
cout << convert(s,4) << endl;
//LeetCode152
nums = {2,3,-2,4};
cout << maxProduct(nums) << endl;
//LeetCode8
cout << str2int(" -1234") << endl;
//LeetCode41
nums = {1,-1,3,4};
cout << firstMissingPositive(nums) << endl;
//LeetCode283
nums = {0,0,0,1,2,0,3,5,6};
moveZeroes(nums);
print(nums);
//LeetCode141
LinkNode n11(3);
LinkNode n22(2);
LinkNode n33(0);
LinkNode n44(-4);
n11.next = &n22;
n22.next = &n33;
n33.next = &n44;
n44.next = &n22;
cout << hasCycleNode(&n11) << endl;
//LeetCode98
TreeNode b0(1);
TreeNode b1(2);
TreeNode b2(3);
b1.left = &b0;
b1.right = &b2;
cout << isValidBST(&b1) << endl;
// LeetCode124
TreeNode a0(-10);
TreeNode a1(9);
TreeNode a2(20);
TreeNode a3(15);
TreeNode a4(7);
a0.left = &a1;
a0.right = &a2;
a2.left = &a3;
a2.right = &a4;
cout << maxSum(&a0)<<endl;
//LeetCode105
vector<vector<int>>tmp;
vector<int>preV{3,9,1,2,20,15,7};
vector<int>inV{1,9,2,3,15,20,7};
levelOrder(buildTreeFromPreIn(preV,inV),tmp);
print(tmp);
//LeetCode34
nums = {5,7,7,8,8,10};
target = 8;
nums = {5,7,7,8,8,10};
target = 6;
print(searchRange(nums,target));
//LeetCode239
nums={1,3,-1,-3,5,3,6,7};
k = 3;
print(maxSlidingWindow(nums,k));
//LeetCode142
cout << detectCycleNode(&n11)->val << endl;
//LeetCode139 单词拆分
string str = "leetcode";
vector<string>wordDict{"leet","code"};
cout << wordBreak(str,wordDict) << endl;
//LeetCode145
nums = {2,3,1,1,4};
cout << jump(nums) << endl;
//LeetCode169
nums = {2,2,1,1,1,2,2};
cout << majorNum(nums) << endl;
//LeetCode234
nums = {1,2,2,1};
cout << isPalindrome(generateLinkNode(nums)) << endl;
//LeetCode62
cout << uniquePaths(3,2) << endl;
cout << uniquePathsI(3,2) << endl;
//LeetCode189
nums = {1,2,3,4,5,6,7};
k = 3;
rotate(nums,k);
print(nums);
//LeetCode94
TreeNode a(0);
TreeNode b(1);
TreeNode c(2);
TreeNode d(3);
TreeNode e(4);
TreeNode f(5);
TreeNode g(6);
b.left = &d;
b.right = &e;
c.left = &f;
c.right = &g;
a.left = &b;
a.right = &c;
TreeNode root = a;
vector<int>res1;
inorder(&root);
inorder(&root,res1);
print(res1);
//LeetCode56
vector<pair<int,int>>intervals{{1,3},{2,6},{8,10},{9,18}};
print(merge(intervals));
//LeetCode88
vector<int>nums1{1,2,3,0,0,0};
nums2 = {2,5,6};
int m = 3;
n = 3;
merge(nums1,m,nums2,n);
print(nums1);
//LeetCode560
nums = {1,2,3};
k = 3;
cout << subarraySum(nums,k) << endl;
//LeetCode279 完全平方数
cout << numSquares(12) << endl;
//LeetCode35
nums = {1,3,5,6};
target = 2;
cout << searchInsert(nums,target) << endl;
//LeetCode24
vector<int>head{1,2,3,4};
print(swapPairs(generateLinkNode(head)));
//LeetCode85
vector<vector<string>>matrix{{"1","0","1","0","0"},{"1","0","1","1","1"},{"1","1","1","1","1"},{"1","0","0","1","0"}};
cout << maxRectangle(matrix) << endl;
//LeetCode28
string haystack= "hello",needle = "ll";
cout << strStr(haystack,needle) << endl;
//LeetCode92
nums = {1,2,3,4,5};
int left = 2, right = 4;
print(reverseBetween(generateLinkNode(nums),left,right));
//LeetCode155 MinStack()
//LeetCode79
vector<vector<char>>board{{'A','B','C','E'},{'S','F','C','S'},{'A','D','E','E'}};
string word = "SEE";
cout << exist(board,word) << endl;
//LeetCode27
nums = {3,2,2,3};
int val = 3;
cout << removeElement(nums,val) << endl;
//LeetCode51 N皇后
print1<string>(solveNqueens(4));
//LeetCode75
nums = {2,1,0,0,2,1};
sortColors(nums);
print(nums);
//LeetCode48
vector<vector<int>>matrixs{{1,2,3},{4,5,6},{7,8,9}};
rotate1(matrixs);
for(auto & nums:matrixs)
{
for(auto & num:nums)
{
cout << num << " ";
}
cout << endl;
}
//LeetCode95
auto trees = generateTrees(3);
for(auto tree:trees)
{
cout << "==" << endl;
pre(tree);
cout << "==" << endl;
}
//LeetCode64
vector<vector<int>>grids{{1,3,1},{1,5,1},{4,2,1}};
cout << minPathSum(grids) << endl;
//LeetCode406 根据身高重建队列
vector<vector<int>> people{{7,0},{4,4},{7,1},{5,0},{6,1},{5,2}};
print(reconstructQueue(people));
//LeetCode226 翻转二叉树
//二叉树的三种遍历
TreeNode t0(0);
TreeNode t1(1);
TreeNode t2(2);
TreeNode t3(3);
t0.left = &t1;
t0.right = &t2;
t2.right = &t3;
print(levelOrder(&t0));
cout << "====" << endl;
print(levelOrder(invertTree(&t0)));
print(levelOrder(dfs_invertTree(&t0)));
cout << "====" << endl;
print(levelOrder(bfs_invertTree(&t0)));
//LeetCode437
cout << pathSum(&t0,2) << endl;
//LeetCode104 二叉树的最大深度
cout << getDepth(&n0) << endl;
cout << getDepth_q(&n0) << endl;
//LeetCode237
nums = {1,2,3,4,5};
node = generateLinkNode(nums);
print(node);
deleteNode(node->next->next);
print(node);
//LeetCode337
TreeNode nn0(3);
TreeNode nn1(2);
TreeNode nn2(3);
TreeNode nn3(3);
TreeNode nn4(1);
nn0.left = &nn1;
nn0.right = &nn2;
nn1.right = &nn3;
nn2.right = &nn4;
// cout << rob(&n0) << endl;
cout << rob1(&nn0) << endl;
////LeetCode18
vector<int>nums5{ 2,2,2,2,2 };
target = 8;
auto res = fourSum(nums5, target);
print(res);
//LeetCode91
string sss = "12";
cout << numDecodings(sss) << endl;
//LeetCode37
cout << "======" << endl;
vector<vector<string>>griddd=
{{"5","3",".",".","7",".",".",".","."},
{"6",".",".","1","9","5",".",".","."},
{".","9","8",".",".",".",".","6","."},
{"8",".",".",".","6",".",".",".","3"},
{"4",".",".","8",".","3",".",".","1"},
{"7",".",".",".","2",".",".",".","6"},
{".","6",".",".",".",".","2","8","."},
{".",".",".","4","1","9",".",".","5"},
{".",".",".",".","8",".",".","7","9"}};
// print();
auto strs = solveSudoku(griddd);
for(auto str:strs)
{
for(auto & s:str)
{
cout << s << " ";
}
cout << endl;
}
//leetcode207
vector<vector<int>>pres{{1,0}};
cout << canFinish(2,pres) << endl;
//LeetCode416 分割等和子集
nums = {1,5,11,5};
cout << canPartition(nums) << endl;
//LeetCode238
nums = {1,2,3,4};
print(productExceptSelf(nums));
//LeetCode114
//flatten()
//LeetCode1
nums = { 2,7,11,5 };
target = 9;
print(twoSum(nums, target));
//LeetCode2
LinkNode* ll1 = new LinkNode(2);
ll1->next = new LinkNode(4);
ll1->next->next = new LinkNode(3);
LinkNode* ll2 = new LinkNode(5);
ll2->next = new LinkNode(6);
ll2->next->next = new LinkNode(4);
print(addTwoNumbers(ll1,ll2));
//LeetCode3
s = "abcabcbb";
cout << lengthofLongestSubString(s) << endl;
//LeetCode4
nums1 = {1,3};
nums2 = {2};
cout << findMediaSorted(nums1,nums2) << endl;
//LeetCode5
s = "babad";
cout << longestPalindrome(s) << endl;
//LeetCode461
cout << hammingDistance(1,4) << endl;
//LeetCode617 合并二叉树
TreeNode tr0(1);
TreeNode tr1(3);
TreeNode tr2(2);
TreeNode tr3(5);
TreeNode tl0(2);
TreeNode tl1(1);
TreeNode tl2(3);
TreeNode tl3(4);
TreeNode tl4(7);
tr0.left = &tr1;
tr0.right = &tr2;
tr1.left = &tr3;
tl0.left = &tl1;
tl0.right = &tl2;
tl1.right = &tl3;
tl2.right = &tl4;
print(levelOrder(&tr0));
print(levelOrder(&tl0));
print(levelOrder(mergeTree(&tr0,&tl0)));
print(levelOrder(mergeTree_q(&tr0,&tl0)));
//LeetCode448
nums = {4,3,2,7,8,2,3,1};
print(findDisappearedNumbers(nums));
//LeetCode543
cout << diameterOfBinaryTree(&tr0) << endl;
//LeetCode338
print(countBits(3));
//LeetCode538
print(levelOrder(convertBST(&t0)));
//LeetCode739
nums = {73,74,75,71,69,72,76,73};
print(dailyTemperatures(nums));
//Leetcode49
vector<string>sss2{"eat", "tea", "tan", "ate", "nat", "bat"};
auto rrr = groupAnagrams(sss2);
for(auto& r:rrr)
{
for(auto& s:r)
cout << s << " ";
cout << endl;
}
cout << endl;
//LeetCode647 回文子串个数
s0 = "abc";
cout << countSubStrings(s0) << endl;
//LeetCode215
nums = {2,3,4,5,6,7,7};
cout << findKthLargest(nums,3) << endl;
cout << findKthLargest_q(nums,3) << endl;
//LeetCode347
nums = {1,1,1,2,2,3};
k = 2;
print(topKFrequent(nums,k));
//LeetCode309
prices = {1,2,3,0,2};
// prices = {1};
cout << maxProfit_cold(prices) << endl;
//LeetCode394
cout << decodeString("3[a]2[bc]");
//LeetCode438
print(findAnagrams("cbaebabacd","abc"));
//LeetCode240
vector<vector<int>>mm{{1,2,3,4},{2,3,4,5},{2,3,43,5},{34,34,3,2}};
cout << searchMatrix(mm,3) << endl;
//LeetCode494
nums = {1,1,1,1,1};
target = 3;
cout << findTargetSumWays(nums,target) << endl;
//LeetCode221
vector<vector<char>>square{{'1','0','0'},{'1','1','1'},{'1','1','1'}};
cout << maximalSquare(square) <<endl;
//LeetCode581
nums = {2,6,4,8,10,9,15};
cout << findUnsortedSubarray(nums) << endl;
//LeetCode312
nums = {3,1,5,8};
cout << maxCoins(nums) << endl;
//LeetCode128
nums = {100,4,200,1,3,2};
cout << longestConsecutive(nums) << endl;
//LeetCode301
s = "()())()";
print(removeInvalidParentheses(s));
return 0;
}