链表专题
LeetCode 19. Remove Nth Node From End of List
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
auto dummy = new ListNode(-1);
dummy->next = head;
auto first = dummy, second = dummy;
while(n--) first = first->next;
while(first->next)
{
first = first->next;
second = second->next;
}
second->next = second->next->next;
return dummy->next;
}
};
LeetCode 83. Remove Duplicates from Sorted List
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
auto cur = head;
while(cur)
{
if(cur->next && cur->next->val == cur->val)
{
cur->next = cur->next->next;
}
else
{
cur = cur->next;
}
}
return head;
}
};
LeetCode 206. Reverse Linked List
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(!head) return NULL;
auto a = head, b = head->next;
while(b)
{
auto c = b->next;
b->next = a;
a = b, b = c;
}
head->next = NULL;
return a;
}
};
LeetCode 92. Reverse Linked List II
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
if(m == n) return head;
auto dummy = new ListNode(-1);
dummy->next = head;
auto a = dummy, d = dummy;
for(int i = 0; i < m - 1; i++) a = a->next;
for(int i = 0; i < n; i++) d = d->next;
auto b = a->next, c = d->next;
for(auto p = b, q = b->next; q != c;)
{
auto o = q->next;
q->next = p;
p = q, q = o;
}
b->next = c;
a->next = d;
return dummy->next;
}
};
LeetCode 61. Rotate List
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
if(!head)return NULL;
int n = 0;
for(auto p = head; p; p = p->next)n++;
k %= n;
auto first = head, second = head;
while(k--) first = first->next;
while(first->next)
{
first = first->next;
second = second->next;
}
first->next = head;
head = second->next;
second->next = NULL;
return head;
}
};
LeetCode 143. Reorder List
class Solution {
public:
void reorderList(ListNode* head) {
if(!head || !head->next || !head->next->next) return;
ListNode* dummy = new ListNode(0);
dummy->next = head;
while(head->next && head->next->next)
{
ListNode* tail = head;
while(tail->next->next) tail = tail->next;
tail->next->next = head->next;
head->next = tail->next;
tail->next = NULL;
head = head->next->next;
}
}
};
LeetCode 21. Merge Two Sorted Lists
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode *dummy = new ListNode(0);
ListNode *cur = dummy;
while(l1 != NULL && l2 != NULL)
{
if(l1->val < l2->val)
{
cur->next = l1;
l1 = l1->next;
}
else
{
cur->next = l2;
l2 = l2->next;
}
cur = cur->next;
}
cur->next = (l1 != NULL ? l1:l2);
return dummy->next;
}
};
LeetCode 160. Intersection of Two Linked Lists
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
auto p = headA, q = headB;
while(p != q)
{
if(p) p = p->next;
else p = headB;
if(q) q = q->next;
else q = headA;
}
return p;
}
};
LeetCode 141. Linked List Cycle
class Solution {
public:
bool hasCycle(ListNode *head) {
if(!head || !head->next) return 0;
ListNode *first = head, *second = first->next;
while(first && second)
{
if(first == second) return true;
first = first->next;
second = second->next;
if(second) second = second = second->next;
}
return false;
}
};
LeetCode 147. Insertion Sort List
class Solution {
public:
ListNode* insertionSortList(ListNode* head) {
ListNode *dummy = new ListNode(-1);
while(head)
{
ListNode *next = head->next;
ListNode *p = dummy;
while(p->next && p->next->val <= head->val) p = p->next;
head->next = p->next;
p->next = head;
head = next;
}
return dummy->next;
}
};
LeetCode 138. Copy List with Random Pointer
class Solution {
public:
unordered_map<Node*, Node*> visHash;
Node* copyRandomList(Node* head) {
if(!head)
return NULL;
if(visHash.count(head))
return visHash[head];
Node* root = new Node(head->val, NULL, NULL);
visHash[head] = root;
root->next = copyRandomList(head->next);
root->random = copyRandomList(head->random);
return root;
}
};
LeetCode 142. Linked List Cycle II
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
auto fast = head, slow = head;
while(slow)
{
fast = fast->next;
slow = slow->next;
if(slow) slow = slow->next;
else break;
if(fast == slow)
{
slow = head;
while(slow != fast)
{
fast = fast->next;
slow = slow->next;
}
return slow;
}
}
return NULL;
}
};
LeetCode 148. Sort List
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 146. LRU Cache
class LRUCache {
public:
struct Node{
int key;
Node *prev, *nxt;
Node(int k)
{
key = k;
prev = nxt = nullptr;
}
};
int c, tot;
Node *head, *tail;
unordered_map<int, pair<int, Node*>> dic;
LRUCache(int capacity) {
tot = 0;
c = capacity;
Node *dummy1 = new Node(-1);
Node *dummy2 = new Node(-1);
head = dummy1;
tail = dummy2;
head->nxt = tail;
tail->prev = head;
}
int get(int key) {
if(dic.find(key) == dic.end())
return -1;
Node *node = dic[key].second;
node->prev->nxt = node->nxt;
node->nxt->prev = node->prev;
node->nxt = tail;
node->prev = tail->prev;
tail->prev->nxt = node;
tail->prev = node;
return dic[key].first;
}
void put(int key, int value) {
if(dic.find(key) != dic.end())
{
dic[key].first = value;
Node *node = dic[key].second;
node->prev->nxt = node ->nxt;
node->nxt->prev = node ->prev;
node->nxt = tail;
node->prev = tail->prev;
tail->prev->nxt = node;
tail->prev = node;
}
else
{
if(tot == c)
{
Node *node = head->nxt;
dic.erase(node->key);
head->nxt = node->nxt;
node->nxt->prev = head;
delete node;
tot--;
}
Node *node = new Node(key);
dic[key] = make_pair(value, node);
node->nxt = tail;
node->prev = tail->prev;
tail->prev->nxt = node;
tail->prev = node;
tot++;
}
}
};
DFS+回溯专题
LeetCode 17. Letter Combinations of a Phone Number
class Solution {
public:
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;
}
void dfs(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;
}
void dfs(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;
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;
}
void dfs(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;
}
void dfs(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;
void dfs(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;
}
void dfs(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;
void solve(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:
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());
return dfs(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;
int totalNQueens(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;
}
void dfs(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};
void solveSudoku(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] != '.') return dfs(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;
}
void dfs(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;
}
long long 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++;
else if(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++;
else if(s[i] == ')') cnt--;
if(cnt < 0) return false;
}
return cnt == 0;
}
void dfs(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);
else if(s[i] == ')' && r > 0) dfs(cur, i, l, r - 1);
}
}
}
};
树专题
LeetCode 101. Symmetric Tree
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
class Solution {
public:
int maxDepth(TreeNode* root) {
return root ? max(maxDepth(root->left), maxDepth(root->right)) + 1 : 0;
}
};
LeetCode 145. Binary Tree Postorder Traversal
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
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;
return dfs(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) return NULL;
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();
}
void dfs(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;
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
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;
}
void dfs(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
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
class Solution {
public:
int ans = 0;
int diameterOfBinaryTree(TreeNode* root) {
dfs(root);
return ans;
}
int dfs(TreeNode *root)
{
if(!root) return 0;
auto left = dfs(root->left);
auto right = dfs(root->right);
ans = max(ans, left + right);
return max(left+1, right+1);
}
};
LeetCode 124. Binary Tree Maximum Path Sum
class Solution {
public:
int ans = INT_MIN;
int maxPathSum(TreeNode* root) {
dfs(root);
return ans;
}
int dfs(TreeNode *root)
{
if(!root) return 0;
auto left = dfs(root->left);
auto right = dfs(root->right);
ans = max(ans, left + root->val + right);
return max(0, root->val + max(left, right));
}
};
LeetCode 87. Scramble String
class Solution {
public:
bool isScramble(string s1, string s2) {
if (s1 == s2) return true;
string ss1 = s1, ss2 = s2;
sort(ss1.begin(), ss1.end()), sort(ss2.begin(), ss2.end());
if (ss1 != ss2) return false;
for (int i = 1; i < s1.size(); i ++ )
{
if (isScramble(s1.substr(0, i), s2.substr(0, i))
&& isScramble(s1.substr(i), s2.substr(i)))
return true;
if (isScramble(s1.substr(0, i), s2.substr(s2.size() - i))
&& isScramble(s1.substr(i), s2.substr(0, s2.size() - i)))
return true;
}
return false;
}
};
LeetCode 117. Populating Next Right Pointers in Each Node II
class Solution {
public:
Node* connect(Node* root) {
if(!root) return root;
queue<pair<Node*, int>> q;
if(root->left) q.push(make_pair(root->left, 1));
if(root->right) q.push(make_pair(root->right, 1));
int flag = 0;
Node* temp;
while(!q.empty())
{
int level = q.front().second;
Node* node = q.front().first;
q.pop();
if(node->left) q.push(make_pair(node->left, level+1));
if(node->right) q.push(make_pair(node->right, level+1));
if(level == flag)
{
temp->next = node;
temp = node;
}
else
{
flag = level;
temp = node;
}
}
return root;
}
};
LeetCode 99. Recover Binary Search Tree
class Solution {
public:
void recoverTree(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
class Solution {
public:
unordered_map<TreeNode*, unordered_map<int, int>>f;
int rob(TreeNode* root) {
dfs(root);
return max(f[root][0], f[root][1]);
}
void dfs(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:
int maxSubArray(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:
int lengthOfLIS(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:
int minDistance(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:
int maxProfit(vector<int>& prices) {
if(prices.size() < 2) return 0;
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:
int maxProfit(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:
int maxProfit(vector<int>& prices) {
int n = prices.size();
if(!n) return 0;
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& 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:
int maxProfit(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;
}
return max(f,g);
}
};
LeetCode 198. House Robber
class Solution {
public:
int rob(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];
}
return max(f[n], g[n]);
}
};
LeetCode 213. House Robber II
class Solution {
public:
int rob(vector<int>& nums) {
int n = nums.size();
if(n == 0) return 0;
if(n == 1) return nums[0];
if(n == 2) return max(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:
int maxCoins(vector<int>& nums) {
int n = nums.size();
nums.insert(nums.begin(), 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:
int numTrees(int n) {
vector<int> f(n+1);
f[0] = 1;
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;
}
void dfs(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;
}
};
LeetCode 49. Group Anagrams
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string, vector<string> > hash;
for(auto str : strs)
{
string key = str;
sort(key.begin(), key.end());
hash[key].push_back(str);
}
vector<vector<string> > res;
for(auto item : hash) res.push_back(item.second);
return res;
}
};
LeetCode 151. Reverse Words in a String
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:
int compareVersion(string s1, string s2) {
int i = 0, j = 0;
while(i < s1.size() || j < s2.size())
{
int x = i, y = j;
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) return 1;
if(a < b) return -1;
i = x + 1, j = y + 1;
}
return 0;
}
};
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", ""};
string numberToWords(int num) {
if(!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:
int lengthOfLongestSubstring(string s) {
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) {
long long 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;
if(!n)
{
if(minus && res != "0") return '-' + res;
return res;
}
res += '.';
unordered_map<long long, 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:
struct Node
{
bool is_end;
Node *son[26];
Node()
{
is_end = false;
for(int i = 0; i < 26; i++) son[i] = NULL;
}
}*root;
Trie() {
root = new Node();
}
void insert(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;
}
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;
}
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;
}
};
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;
}
void dfs(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:
int calculate(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())
{
if(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();
}
else if(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:
int check(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;
}
};
二分与单调队列/栈专题
LeetCode 69. Sqrt(x)
class Solution {
public:
int mySqrt(int x) {
int l = 0, r = x;
while(l < r)
{
int mid = (long long)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++;
else if(t > target) col--;
else return true;
}
return false;
}
};
LeetCode 153. Find Minimum in Rotated Sorted Array
class Solution {
public:
int findMin(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:
int findPeakElement(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
class MinStack {
public:
stack<int> stk, stk_min;
MinStack() {
}
void push(int x) {
stk.push(x);
if(stk_min.empty()) stk_min.push(x);
else stk_min.push(min(x, stk_min.top()));
}
void pop() {
stk.pop();
stk_min.pop();
}
int top() {
return stk.top();
}
int getMin() {
return stk_min.top();
}
};
LeetCode 496. Next Greater Element I
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& findNums, vector<int>& nums) {
stack<int> stk;
unordered_map<int, int> hash;
for(int j = nums.size() - 1; j >= 0; j--)
{
while(stk.size() && stk.top() <= nums[j]) stk.pop();
hash[nums[j]] = stk.size() ? stk.top() : - 1;
stk.push(nums[j]);
}
vector<int> res;
for(auto x : findNums) res.push_back(hash[x]);
return res;
}
};
LeetCode 42. Trapping Rain Water
class Solution {
public:
int trap(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:
int largestRectangleArea(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:
int findRadius(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:
double findMedianSortedArrays(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
{
return findKthNumber(nums1, 0, nums2, 0, total / 2 + 1);
}
}
int findKthNumber(vector<int> &nums1, int i, vector<int> &nums2, int j, int k)
{
if (nums1.size() - i > nums2.size() - j) return findKthNumber(nums2, j, nums1, i, k);
if (nums1.size() == i) return nums2[j + k - 1];
if (k == 1) return min(nums1[i], nums2[j]);
int si = min(i + k / 2, int(nums1.size())), sj = j + k / 2;
if (nums1[si - 1] > nums2[sj - 1])
{
return findKthNumber(nums1, i, nums2, j + k / 2, k - k / 2);
}
else
{
return findKthNumber(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:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
unordered_map<int, int> hash;
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:
int subarraySum(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:
int findMaxLength(vector<int>& nums) {
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++)
{
string str = s.substr(i, 10);
hash[str]++;
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) {
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:
const static int 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;
}
void put(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;
}
int get(int key) {
auto it = find(key);
if (it == hash[key % N].end())
return -1;
return it->second;
}
void remove(int key) {
int t = key % N;
auto it = find(key);
if (it != hash[t].end())
hash[t].erase(it);
}
};
LeetCode 652. Find Duplicate Subtrees
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) return to_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);
return to_string(t);
}
vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {
hash["#"] = ++cnt;
dfs(root);
return ans;
}
};
LeetCode 290. Word Pattern
class Solution {
public:
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:
int leastBricks(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:
int maxPoints(vector<vector<int>>& points) {
if(points.empty()) return 0;
int res = 1;
for(int i = 0; i < points.size(); i++)
{
unordered_map<long double, 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])
{
long double slope = (long double)(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:
unordered_map<int, vector<pair<int, int>>> posts;
unordered_map<int, unordered_set<int>> follows;
int id = 0;
Twitter() {
}
void postTweet(int userId, int tweetId) {
posts[userId].push_back(make_pair(id++, tweetId));
}
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;
}
void follow(int followerId, int followeeId) {
if(followerId != followeeId)
follows[followerId].insert(followeeId);
}
void unfollow(int followerId, int followeeId) {
follows[followerId].erase(followeeId);
}
};
LeetCode 128. Longest Consecutive Sequence
class Solution {
public:
int longestConsecutive(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:
int minimumTotal(vector<vector<int>>& nums) {
int n = nums.size();
vector<vector<long long>> f(2, vector<long long>(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]);
}
long long 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:
int uniquePathsWithObstacles(vector<vector<int>>& g) {
int n = g.size(), m = g[0].size();
vector<vector<long long>> f(n, vector<long long>(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];
}
int maxEnvelopes(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;
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};
int dp(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];
}
int longestIncreasingPath(vector<vector<int>>& matrix) {
if(matrix.empty()) return 0;
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;
}
};
LeetCode 322. Coin Change
class Solution {
public:
int INF = 1000000000;
int coinChange(vector<int>& coins, int amount) {
vector<int> f(amount+1, INF);
f[0] = 0;
for(int i = 0; i < coins.size(); i++)
for(int j = coins[i]; j <= amount; j++)
f[j] = min(f[j], f[j - coins[i]] + 1);
if(f[amount] == INF) f[amount] = -1;
return f[amount];
}
};
LeetCode 221. Maximal Square
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
if(matrix.empty()) return 0;
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;
int findPaths(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)));
return dp(m, n, N, i, j);
}
int dp(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:
int numDecodings(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:
int nthUglyNumber(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:
int numDistinct(string s, string t) {
int n = s.size(), m = t.size();
vector<vector<long long>> f(n + 1, vector<long long>(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:
int minCut(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);
}
return max(0, f[n] - 1);
}
};
LeetCode 526. Beautiful Arrangement
class Solution {
public:
int countArrangement(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;
}
};