Leetcode C++

Lakukan tugas rumah & ujian kamu dengan baik sekarang menggunakan Quizwiz!

DP class Solution { public: int climbStairs(int n) { vector<int> dp(n+1, 1); for (int i = 2; i <= n; i++) dp[i] = dp[i-1] + dp[i-2]; return dp[n]; } };

70. Climbing Stairs You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

Fast&Slow Pointers class Solution { public: void moveZeroes(vector<int>& nums) { int slow = 0, fast = 0; while (fast < nums.size()){ if (nums[fast] != 0) swap(nums[slow++], nums[fast]); fast++; } } };

283. Move Zeroes Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements. Example: Input: [0,1,0,3,12] Output: [1,3,12,0,0]

Hashmap class Solution { public: vector<int> intersect(vector<int>& nums1, vector<int>& nums2) { unordered_map<int, int> hash; vector<int> res; for (auto m : nums1) hash[m]++; for (auto m : nums2){ if (hash[m]-- > 0) res.push_back(m); } return res; } };

350. Intersection of Two Arrays II Given two arrays, write a function to compute their intersection. Input: nums1 = [1,2,2,1], nums2 = [2,2] Output: [2,2]

DP class Solution { public: vector<vector<int>> generate(int numRows) { vector<vector<int>> res(numRows, vector<int>()); for (int i = 0; i < numRows; i++){ res[i].resize(i+1, 1); for (int j = 1; j < i; j++) res[i][j] = res[i-1][j-1] + res[i-1][j]; } return res; } };

118. Pascal's Triangle Given an integer numRows, return the first numRows of Pascal's triangle.

Stack class MinStack { public: /** initialize your data structure here. */ stack<int> s1, s2; MinStack() { } void push(int x) { s1.push(x); if (s2.empty()) s2.push(x); else s2.push(min(x, s2.top())); } void pop() { s1.pop(); s2.pop(); } int top() { return s1.top(); } int getMin() { return s2.top(); } };

155. Min Stack

One Pass class Solution { public: int countPrimes(int n) { int res = 0; vector<bool> isPrime(n, true); for(int i = 2; i < n; i++){ if (!isPrime[i]) continue; res++; for (int j = 2; j*i < n; j++) isPrime[i*j] = false; } return res; } };

204. Count Primes Count the number of prime numbers less than a non-negative number, n. Input: n = 10 Output: 4

Dynamic Programming class Solution { public: int numTrees(int n) { vector<int> dp(n+1, 0); dp[0] = 1; dp[1] = 1; for (int i = 2; i <= n; ++i){ for (int k = 0; k < i; ++k) dp[i] += dp[k] * dp[i-k-1]; } return dp[n]; } };

96. Unique Binary Search Trees Given an integer n, return the number of structurally unique BST's (binary search trees) which has exactly n nodes of unique values from 1 to n.

Slow & fast pointers class Solution { public: ListNode *detectCycle(ListNode *head) { if (head == nullptr) return NULL; bool isCycle = false; ListNode *fast = head, *slow = head; while (fast && fast->next){ slow = slow->next; fast = fast->next->next; if (fast == slow){ isCycle = true; break; } } if (!isCycle) return NULL; slow = head; while (slow != fast){ slow = slow->next; fast = fast->next; } return slow; } };

142. Linked List Cycle II Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

Hashmap class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { vector<int> res(2, -1); unordered_map<int, int> hash; for (int i = 0; i < nums.size(); i++){ if (hash.count(target-nums[i])){ res[0] = hash[target-nums[i]]; res[1] = i; return res; } hash[nums[i]] = i; } return res; } };

1. Two Sum Input: nums = [2,7,11,15], target = 9 Output: [0,1] Output: Because nums[0] + nums[1] == 9, we return [0, 1].

DP class Solution { public: bool isMatch(string s, string p) { int m = s.size(), n = p.size(); vector<vector<bool>> dp(m+1, vector<bool>(n+1, false)); dp[0][0] = true; for (int j = 1; j <= n; j++) if ((p[j-1] == '*') && (j >= 2)) dp[0][j] = dp[0][j-2]; for (int i = 1; i <= m; i++) for (int j = 1; j <= n; j++){ if (s[i-1] == p[j-1] || p[j-1] == '.') dp[i][j] = dp[i-1][j-1]; if ((p[j-1] == '*') && (j >= 2)) dp[i][j] = dp[i][j-2] || (dp[i-1][j] && (s[i-1] == p[j-2] || p[j-2] == '.')); } return dp[m][n]; } };

10. Regular Expression Matching Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*' where: '.' Matches any single character.​​​​ '*' Matches zero or more of the preceding element. The matching should cover the entire input string (not partial).

Recursive class Solution { public: bool isSameTree(TreeNode* p, TreeNode* q) { if (p == nullptr && q == nullptr) return true; if (p == nullptr || q == nullptr) return false; if (p->val != q->val) return false; return (isSameTree(p->left, q->left) && isSameTree(p->right, q->right)); } };

100. Same Tree Given two binary trees, write a function to check if they are the same or not. Two binary trees are considered the same if they are structurally identical and the nodes have the same value.

Recursion /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: bool isSymmetric(TreeNode* root) { return root == nullptr || isSymmetric(root->left, root->right); } bool isSymmetric(TreeNode* p, TreeNode* q){ if (p == nullptr && q == nullptr) return true; if (p == nullptr || q == nullptr) return false; return (p->val == q->val) && isSymmetric(p->left, q->right) && isSymmetric(p->right, q->left); } };

101. Symmetric Tree

Recursive class Solution { public: bool isSymmetric(TreeNode* root) { return root == nullptr || isSymmetricTree(root->left, root->right); } bool isSymmetricTree(TreeNode* p, TreeNode* q) { if (p == nullptr && q == nullptr) return true; if (p == nullptr || q == nullptr) return false; if (p->val != q->val) return false; return isSymmetricTree(p->left, q->right) && isSymmetricTree(p->right, q->left); } };

101. Symmetric Tree Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

Queue /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { vector<vector<int>> res; queue<TreeNode*> q; if (root == nullptr) return res; q.push(root); while (!q.empty()){ int len = q.size(); vector<int> temp; for (int i = 0; i < len; ++i){ TreeNode* p = q.front(); q.pop(); temp.push_back(p->val); if (p->left != nullptr) q.push(p->left); if (p->right != nullptr) q.push(p->right); } res.push_back(temp); } return res; } };

102. Binary Tree Level Order Traversal

Greedy class Solution { public: int videoStitching(vector<vector<int>>& clips, int T) { sort(clips.begin(), clips.end()); int i = 0, curr_e = 0, next_e = 0, res = 0; while (curr_e < T){ while (i < clips.size() && clips[i][0] <= curr_e) next_e = max(next_e, clips[i++][1]); if (curr_e == next_e) return -1; curr_e = next_e; res++; } return res; } };

1024. Video Stitching You are given a series of video clips from a sporting event that lasted T seconds. These video clips can be overlapping with each other and have varied lengths. Each video clip clips[i] is an interval: it starts at time clips[i][0] and ends at time clips[i][1]. We can cut these clips into segments freely: for example, a clip [0, 7] can be cut into segments [0, 1] + [1, 3] + [3, 7]. Return the minimum number of clips needed so that we can cut the clips into segments that cover the entire sporting event ([0, T]). If the task is impossible, return -1. Input: clips = [[0,2],[4,6],[8,10],[1,9],[1,5],[5,9]], T = 10 Output: 3

Stack class Solution { public: vector<vector<int>> zigzagLevelOrder(TreeNode* root) { vector<vector<int>> res; if (root == nullptr) return res; vector<int> level; queue<TreeNode*> que; que.push(root); que.push(nullptr); TreeNode* curr; int depth = 0; while (que.size() > 0){ curr = que.front(); que.pop(); if (curr){ if (depth%2 == 1) level.insert(level.begin(), curr->val); else level.push_back(curr->val); if (curr->left) que.push(curr->left); if (curr->right) que.push(curr->right); } else{ res.push_back(level); level.resize(0); if (que.size() > 0) que.push(nullptr); depth++; } } return res; } };

103. Binary Tree Zigzag Level Order Traversal

Recursion /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: int maxDepth(TreeNode* root) { if (root == nullptr) return 0; int left = maxDepth(root->left); int right = maxDepth(root->right); return max(left, right) + 1; } };

104. Maximum Depth of Binary Tree

Recursive class Solution { public: int maxDepth(TreeNode* root) { if (root == nullptr) return 0; if (root->left == nullptr && root->right == nullptr) return 1; int maxLeft = maxDepth(root->left); int maxRight = maxDepth(root->right); return max(maxLeft, maxRight) + 1; } };

104. Maximum Depth of Binary Tree

Recursion /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { return helper(preorder, 0, preorder.size()-1, inorder, 0, inorder.size()-1); } TreeNode* helper(vector<int>& preorder, int pleft, int pright, vector<int>& inorder, int ileft, int iright){ if (pleft > pright) return nullptr; TreeNode* root = new TreeNode(preorder[pleft]); int i = ileft; for (; i <= iright; ++i) if (inorder[i] == preorder[pleft]) break; root->left = helper(preorder, pleft+1, pleft+i-ileft, inorder, ileft, i-1); root->right = helper(preorder, pleft+i-ileft+1, pright, inorder, i+1, iright); return root; } };

105. Construct Binary Tree from Preorder and Inorder Traversal Given preorder and inorder traversal of a tree, construct the binary tree.

Recursive class Solution { public: TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { return helper(preorder, 0, preorder.size()-1, inorder, 0, inorder.size()-1); } TreeNode* helper(vector<int>& preorder, int s1, int e1, vector<int>& inorder, int s2, int e2){ if (s1 > e1) return nullptr; TreeNode *root = new TreeNode(preorder[s1]); int i = s2; for (; i <= e2; i++) if (preorder[s1] == inorder[i]) break; int leftnum = i - s2; root->left = helper(preorder, s1+1, s1+leftnum, inorder, s2, s2+leftnum-1); root->right = helper(preorder, s1+leftnum+1, e1, inorder, s2+leftnum+1, e2); return root; } };

105. Construct Binary Tree from Preorder and Inorder Traversal Given preorder and inorder traversal of a tree, construct the binary tree.

Recursion /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { return helper(inorder, 0, inorder.size()-1, postorder, 0, postorder.size()-1); } TreeNode* helper(vector<int>& inorder, int ileft, int iright, vector<int>& postorder, int pleft, int pright){ if (pleft > pright) return nullptr; TreeNode* root = new TreeNode(postorder[pright]); int i = ileft; for (; i <= iright; ++i) if (inorder[i] == postorder[pright]) break; root->left = helper(inorder, ileft, i-1, postorder, pleft, pleft+i-ileft-1); root->right = helper(inorder, i+1, iright, postorder, pleft+i-ileft, pright-1); return root; } };

106. Construct Binary Tree from Inorder and Postorder Traversal Given inorder and postorder traversal of a tree, construct the binary tree.

Recursive class Solution { public: TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { return helper(inorder, 0, inorder.size()-1, postorder, 0, postorder.size()-1); } TreeNode* helper(vector<int>& inorder, int s1, int e1, vector<int>& postorder, int s2, int e2){ if (s2 > e2) return nullptr; TreeNode* root = new TreeNode(postorder[e2]); int i = s1; for (; i <= e1; i++) if (inorder[i] == postorder[e2]) break; int leftnum = i - s1; root->left = helper(inorder, s1, s1+leftnum-1, postorder, s2, s2+leftnum-1); root->right = helper(inorder, s1+leftnum+1, e1, postorder, s2+leftnum, e2-1); return root; } };

106. Construct Binary Tree from Inorder and Postorder Traversal Given inorder and postorder traversal of a tree, construct the binary tree.

Stack class Solution { public: vector<vector<int>> levelOrderBottom(TreeNode* root) { vector<vector<int>> res; queue<TreeNode*> que; vector<int> level; if (root == nullptr) return res; que.push(root); que.push(nullptr); TreeNode* curr; while (que.size()){ curr = que.front(); que.pop(); if (curr){ level.push_back(curr->val); if (curr->left) que.push(curr->left); if (curr->right) que.push(curr->right); } else{ res.insert(res.begin(), level); level.resize(0); if (que.size() > 0) que.push(nullptr); } } return res; } };

107. Binary Tree Level Order Traversal II

Recursion /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: TreeNode* sortedArrayToBST(vector<int>& nums) { return helper(nums, 0, nums.size()-1); } TreeNode* helper(vector<int>& nums, int left, int right){ if (left > right) return nullptr; int mid = left + (right - left) / 2; TreeNode* root = new TreeNode(nums[mid]); root->left = helper(nums, left, mid-1); root->right = helper(nums, mid+1, right); return root; } };

108. Convert Sorted Array to Binary Search Tree

Recursive class Solution { public: TreeNode* sortedArrayToBST(vector<int>& nums) { return helper(nums, 0, nums.size()-1); } TreeNode* helper(vector<int>& nums, int low, int high){ if (low > high) return nullptr; int mid = (low + high) / 2; TreeNode* root = new TreeNode(nums[mid]); root->left = helper(nums, low, mid-1); root->right = helper(nums, mid+1, high); return root; } };

108. Convert Sorted Array to Binary Search Tree

Recursive class Solution { public: TreeNode* sortedListToBST(ListNode* head) { return helper(head, nullptr); } TreeNode* helper(ListNode* head, ListNode*tail){ if (head == tail) return nullptr; ListNode *fast = head, *slow = head; while (fast!=tail && fast->next != tail){ slow = slow->next; fast = fast->next->next; } TreeNode *root = new TreeNode(slow->val); root->left = helper(head, slow); root->right = helper(slow->next, tail); return root; } };

109. Convert Sorted List to Binary Search Tree

Binary Search class Solution { public: int findInMountainArray(int target, MountainArray &mountainArr) { int n = mountainArr.length(); int left = 0, right = n-1; while (left < right){ int mid = left + (right - left)/2; if (mountainArr.get(mid) > mountainArr.get(mid+1)) right = mid; else left = mid+1; } int top_index = left; int temp = mountainArr.get(top_index); if (temp < target) return -1; if (temp == target) return top_index; left = 0, right = top_index-1; while (left <= right){ int mid = left + (right - left)/2; temp = mountainArr.get(mid); if (temp == target) return mid; else if (temp < target) left = mid + 1; else right = mid - 1; } left = top_index+1, right = n-1; while (left <= right){ int mid = left + (right - left)/2; int temp = mountainArr.get(mid); if (temp == target) return mid; else if (temp > target) left = mid + 1; else right = mid - 1; } return -1; } };

1095. Find in Mountain Array This problem is an interactive problem.) You may recall that an array A is a mountain array if and only if: A.length >= 3 There exists some i with 0 < i < A.length - 1 such that:A[0] < A[1] < ... A[i-1] < A[i]A[i] > A[i+1] > ... > A[A.length - 1] Given a mountain array mountainArr, return the minimum index such that mountainArr.get(index) == target. If such an index doesn't exist, return -1. You can't access the mountain array directly. You may only access the array using a MountainArray interface: MountainArray.get(k) returns the element of the array at index k (0-indexed). MountainArray.length() returns the length of the array. Input: array = [1,2,3,4,5,3,1], target = 3 Output: 2 Explanation: 3 exists in the array, at index=2 and index=5. Return the minimum index, which is 2.

DFS class Solution { public: int numIslands(vector<vector<char>>& grid) { int m = grid.size(), n = grid[0].size(); int res = 0; for (int i = 0; i < m; i++) for (int j = 0; j < n; j++){ if (grid[i][j] == '1'){ dfs(grid, i, j); res++; } } return res; } void dfs(vector<vector<char>>& grid, int i, int j){ int m = grid.size(), n = grid[0].size(); if (i < 0 || i >= m || j < 0 || j>= n || grid[i][j] == '0') return; grid[i][j] = '0'; for (auto d : direction) dfs(grid, i+d[0], j+d[1]); } private: vector<vector<int>> direction{{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; };

200. Number of Islands

Two Pointers class Solution { public: int maxArea(vector<int>& height) { int left = 0, right = height.size() - 1; int res = 0; while (left < right){ int h = min(height[left], height[right]); res = max(res, h * (right - left)); if (height[left] < height[right]) left++; else right--; } return res; } };

11. Container With Most Water Given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water. Note: You may not slant the container and n is at least 2. Example: Input: [1,8,6,2,5,4,8,3,7] Output: 49

Two Pointers class Solution { public: int maxArea(vector<int>& height) { if (height.empty()) return 0; int res = 0, left = 0, right = height.size()-1; while (left < right){ res = max(res, min(height[left], height[right]) * (right-left)); if (height[left] < height[right]) left++; else right--; } return res; } };

11. Container With Most Water Given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of the line i is at (i, ai) and (i, 0). Find two lines, which, together with the x-axis forms a container, such that the container contains the most water. Notice that you may not slant the container.

Recursive class Solution { public: bool isBalanced(TreeNode* root) { if (root == nullptr) return true; int leftDepth = maxDepth(root->left); int rightDepth = maxDepth(root->right); return abs(leftDepth - rightDepth) <= 1 && isBalanced(root->left) && isBalanced(root->right); } int maxDepth(TreeNode* root) { if (root == nullptr) return 0; if (root->left == nullptr && root->right == nullptr) return 1; int leftDepth = maxDepth(root->left); int rightDepth = maxDepth(root->right); return max(leftDepth, rightDepth) + 1; } };

110. Balanced Binary Tree Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced binary tree is defined as: a binary tree in which the left and right subtrees of every node differ in height by no more than 1.

Recursion /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: bool isBalanced(TreeNode* root) { if (root == nullptr) return true; int left_h = maxHeight(root->left); int right_h = maxHeight(root->right); return (abs(left_h - right_h) <= 1) && isBalanced(root->left) && isBalanced(root->right); } int maxHeight(TreeNode* p){ if (p == nullptr) return 0; int left_h = maxHeight(p->left); int right_h = maxHeight(p->right); return max(left_h, right_h) + 1; } };

110. Balanced Binary Tree Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced binary tree is defined as: a binary tree in which the left and right subtrees of every node differ in height by no more than 1.

Recursion /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: int minDepth(TreeNode* root) { if (root == nullptr) return 0; int left = minDepth(root->left); int right = minDepth(root->right); if (left == 0 || right == 0) return left + right + 1; return min(left, right) + 1; } };

111. Minimum Depth of Binary Tree

Recursive class Solution { public: int minDepth(TreeNode* root) { if (root == nullptr) return 0; if (root->left == nullptr && root->right == nullptr) return 1; int leftDepth = minDepth(root->left); int rightDepth = minDepth(root->right); if (leftDepth == 0 || rightDepth == 0) return leftDepth + rightDepth + 1; else return min(leftDepth, rightDepth) + 1; } };

111. Minimum Depth of Binary Tree Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. Note: A leaf is a node with no children.

Recursive class Solution { public: bool hasPathSum(TreeNode* root, int sum) { if (root == nullptr) return false; if (root->left == nullptr && root->right == nullptr && root->val == sum) return true; return hasPathSum(root->left, sum - root->val) || hasPathSum(root->right, sum - root->val); } };

112. Path Sum Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. Note: A leaf is a node with no children.

Recursion /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: bool hasPathSum(TreeNode* root, int targetSum) { if (root == nullptr) return false; if (root->left == nullptr && root->right == nullptr) return targetSum == root->val; return hasPathSum(root->left, targetSum - root->val) || hasPathSum(root->right, targetSum - root->val); } };

112. Path Sum Given the root of a binary tree and an integer targetSum, return true if the tree has a root-to-leaf path such that adding up all the values along the path equals targetSum. A leaf is a node with no children.

Recursive class Solution { public: vector<vector<int>> pathSum(TreeNode* root, int sum) { vector<vector<int>> res; vector<int> path; helper(root, sum, res, path); return res; } void helper(TreeNode *root, int sum, vector<vector<int>>& res, vector<int>& path){ if (root == nullptr) return; path.push_back(root->val); if (root->left == nullptr && root->right == nullptr && sum == root->val) res.push_back(path); helper(root->left, sum - root->val, res, path); helper(root->right, sum - root->val, res, path); path.pop_back(); } };

113. Path Sum II Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum. Note: A leaf is a node with no children.

Stack class MyQueue { public: /** Initialize your data structure here. */ stack<int> s1, s2; MyQueue() { } /** Push element x to the back of queue. */ void push(int x) { s1.push(x); } /** Removes the element from in front of queue and returns that element. */ int pop() { int temp = peek(); s2.pop(); return temp; } /** Get the front element. */ int peek() { if (s2.empty()){ while (!s1.empty()){ s2.push(s1.top()); s1.pop(); } } return s2.top(); } /** Returns whether the queue is empty. */ bool empty() { return s1.empty() && s2.empty(); } };

232. Implement Queue using Stacks

Recursion /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: vector<vector<int>> pathSum(TreeNode* root, int targetSum) { vector<int> path; vector<vector<int>> res; helper(root, path, targetSum, res); return res; } void helper(TreeNode* root, vector<int>& path, int targetSum, vector<vector<int>>& res){ if (root == nullptr) return; path.push_back(root->val); if (root->left == nullptr && root->right == nullptr && root->val == targetSum) res.push_back(path); helper(root->left, path, targetSum-root->val, res); helper(root->right, path, targetSum-root->val, res); path.pop_back(); } };

113. Path Sum II Given the root of a binary tree and an integer targetSum, return all root-to-leaf paths where each path's sum equals targetSum. A leaf is a node with no children.

Recursion /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: void flatten(TreeNode* root) { if (root == nullptr) return; flatten(root->left); flatten(root->right); if (root->left == nullptr) return; TreeNode* p = root->left; while (p->right) p = p->right; p->right = root->right; root->right = root->left; root->left = nullptr; } };

114. Flatten Binary Tree to Linked List Given the root of a binary tree, flatten the tree into a "linked list": The "linked list" should use the same TreeNode class where the right child pointer points to the next node in the list and the left child pointer is always null. The "linked list" should be in the same order as a pre-order traversal of the binary tree.

DP class Solution { public: int longestCommonSubsequence(string text1, string text2) { int m = text1.size(), n = text2.size(); if (m < 1 || n < 1) return 0; vector<vector<int>> dp(m+1, vector<int>(n+1, 0)); for (int i = 1; i <= m; ++i){ for (int j = 1; j <= n; ++j){ if (text1[i-1] == text2[j-1]) dp[i][j] = dp[i-1][j-1] + 1; else dp[i][j] = max(dp[i-1][j], dp[i][j-1]); } } return dp[m][n]; } };

1143. Longest Common Subsequence

DP class Solution { public: int numDistinct(string s, string t) { int m = s.size(), n = t.size(); vector<vector<long>> dp(m+1, vector<long>(n+1, 0)); for (int i = 0; i <= m; i++) dp[i][0] = 1; for (int i = 1; i <= m; i++) for (int j = 1; j <= n; j++) dp[i][j] = dp[i-1][j] + ((s[i-1] == t[j-1])? dp[i-1][j-1] : 0); return dp[m][n]; } };

115. Distinct Subsequences Given two strings s and t, return the number of distinct subsequences of s which equals t.

Stack class Solution { public: Node* connect(Node* root) { if (root == nullptr) return root; Node* p = root; while (p){ Node* next = nullptr; Node* prev = nullptr; while (p){ if (next == nullptr) next = p->left ? p->left : p->right; if (p->left){ if (prev) prev->next = p->left; prev = p->left; } if (p->right){ if (prev) prev->next = p->right; prev = p->right; } p = p->next; } p = next; } return root; } };

117. Populating Next Right Pointers in Each Node II Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL. Initially, all next pointers are set to NULL.

DP class Solution { public: int minimumTotal(vector<vector<int>>& triangle) { int m = triangle.size(); vector<vector<int>> dp(m, vector<int>(m, 0)); dp[0][0] = triangle[0][0]; for (int i = 1; i < m; i++){ dp[i][0] = dp[i-1][0] + triangle[i][0]; dp[i][i] = dp[i-1][i-1] + triangle[i][i]; } for (int i = 2; i < m; i++){ for (int j = 1; j < i; j++) dp[i][j] = min(dp[i-1][j], dp[i-1][j-1]) + triangle[i][j]; } int res = INT_MAX; for (int i = 0; i < m; i++) res = min(res, dp[m-1][i]); return res; } };

120. Triangle Given a triangle array, return the minimum path sum from top to bottom. For each step, you may move to an adjacent number of the row below. More formally, if you are on index i on the current row, you may move to either index i or index i + 1 on the next row.

DP class Solution { public: int maxProfit(vector<int>& prices) { int n = prices.size(); vector<vector<int>> dp(n+1, vector<int>(2, 0)); dp[0][0] = 0; dp[0][1] = INT_MIN; for (int i = 1; i <= n; i++){ dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i-1]); dp[i][1] = max(dp[i-1][1], -prices[i-1]); } return dp[n][0]; } };

121. Best Time to Buy and Sell Stock You are given an array prices where prices[i] is the price of a given stock on the ith day. You want to maximize your profit by choosing a single day to buy one stock and choosing a different day in the future to sell that stock. Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return 0.

DP class Solution { public: int maxProfit(vector<int>& prices) { int n = prices.size(); vector<vector<int>> dp(n+1, vector<int>(2, 0)); dp[0][0] = 0; dp[0][1] = INT_MIN; for (int i = 1; i <= n; i++){ dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i-1]); dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i-1]); } return dp[n][0]; } };

122. Best Time to Buy and Sell Stock II Say you have an array prices for which the ith element is the price of a given stock on day i. Design an algorithm to find the maximum profit. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times). Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).

DP class Solution { public: int maxProfit(vector<int>& prices) { int n = prices.size(); vector<vector<vector<int>>> dp(n+1, vector<vector<int>>(3, vector<int>(2, 0))); for (int k = 0; k < 3; k++) dp[0][k][1] = INT_MIN; for (int i = 1; i <= n; i++) dp[i][0][1] = INT_MIN; for (int i = 1; i <= n; i++) for (int k = 1; k < 3; k++){ dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1] + prices[i-1]); dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i-1]); } return dp[n][2][0]; } };

123. Best Time to Buy and Sell Stock III Say you have an array for which the ith element is the price of a given stock on day i. Design an algorithm to find the maximum profit. You may complete at most two transactions. Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).

Linked List class Solution { public: void deleteNode(ListNode* node) { node->val = node->next->val; node->next = node->next->next; } };

237. Delete Node in a Linked List Write a function to delete a node in a singly-linked list. You will not be given access to the head of the list, instead you will be given access to the node to be deleted directly. It is guaranteed that the node to be deleted is not a tail node in the list.

Recursion /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: int maxPathSum(TreeNode* root) { max_sum = INT_MIN; helper(root); return max_sum; } private: int max_sum; int helper(TreeNode* root){ if (root == nullptr) return 0; int l = helper(root->left); int r = helper(root->right); max_sum = max(max_sum, root->val + max(l, 0) + max(r, 0)); return max(r, l) > 0 ? max(r, l) + root->val : root->val; } };

124. Binary Tree Maximum Path Sum

String class Solution { public: bool isPalindrome(string s) { string filtered, reverse; for (auto c : s) if (isalnum(c)) filtered.push_back(tolower(c)); reverse.resize(filtered.size()); reverse_copy(filtered.begin(), filtered.end(), reverse.begin()); return filtered == reverse; } };

125. Valid Palindrome Given a string s, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. Input: s = "A man, a plan, a canal: Panama" Output: true Explanation: "amanaplanacanalpanama" is a palindrome.

BFS class Solution { public: int ladderLength(string beginWord, string endWord, vector<string>& wordList) { unordered_set<string> dict(wordList.begin(), wordList.end()); if (!dict.count(endWord)) return 0; unordered_set<string> visited; queue<string> q{{beginWord}}; visited.insert(beginWord); int res = 1; while (!q.empty()){ int l = q.size(); for (int i = 0; i < l; i++){ string word = q.front(); q.pop(); for (int j = 0; j < word.size(); j++){ string newWord = word; for (char c = 'a'; c <= 'z'; c++){ newWord[j] = c; if (newWord == endWord) return ++res; if (!dict.count(newWord) || visited.count(newWord)) continue; visited.insert(newWord); q.push(newWord); } } } ++res; } return 0; } };

127. Word Ladder

BFS class Solution { public: int ladderLength(string beginWord, string endWord, vector<string>& wordList) { unordered_set<string> dict(wordList.begin(), wordList.end()); if (!dict.count(endWord)) return 0; unordered_set<string> visited; queue<string> q{{beginWord}}; visited.insert(beginWord); int res = 1; while (!q.empty()){ int len = q.size(); for (int i = 0; i < len; i++){ string word = q.front(); q.pop(); for (int i = 0; i < word.size(); i++){ string newWord = word; for (char c = 'a'; c <= 'z'; ++c){ newWord[i] = c; if (newWord == endWord) return res+1; if (!dict.count(newWord) || visited.count(newWord)) continue; visited.insert(newWord); q.push(newWord); } } } ++res; } return 0; } };

127. Word Ladder Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that: Only one letter can be changed at a time. Each transformed word must exist in the word list. Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"] Output: 5 Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", return its length 5.

Recursion /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: int sumNumbers(TreeNode* root) { return dfs(root, 0); } int dfs(TreeNode* node, int sum){ if (node == nullptr) return 0; int curr_sum = 10 * sum + node->val; if (node->left == nullptr && node->right == nullptr) return curr_sum; return dfs(node->left, curr_sum) + dfs(node->right, curr_sum); } };

129. Sum Root to Leaf Numbers Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. An example is the root-to-leaf path 1->2->3 which represents the number 123. Find the total sum of all root-to-leaf numbers. Note: A leaf is a node with no children.

TreeMap class Solution { public: bool isPossibleDivide(vector<int>& nums, int k) { int n = nums.size(); if (n%k) return false; map<int, int> tree_map; for (auto num : nums) tree_map[num]++; while (!tree_map.empty()){ int start = tree_map.begin()->first; for (int i = 0; i < k; i++){ if (!tree_map.count(start+i)) return false; if (--tree_map[start+i] == 0) tree_map.erase(start+i); } } return true; } };

1296. Divide Array in Sets of K Consecutive Numbers Given an array of integers nums and a positive integer k, find whether it's possible to divide this array into sets of k consecutive numbersReturn True if it is possible. Otherwise, return False. Input: nums = [1,2,3,3,4,4,5,6], k = 4 Output: true Explanation: Array can be divided into [1,2,3,4] and [3,4,5,6].

One Pass class Solution { public: int romanToInt(string s) { unordered_map<char, int> map = {{'I', 1}, {'V', 5}, {'X', 10}, {'L', 50}, {'C', 100}, {'D', 500}, {'M', 1000}}; int res = 0, prev = INT_MAX; for (auto c : s){ res += map[c]; if (map[c] > prev) res -= 2*prev; prev = map[c]; } return res; } };

13. Roman to Integer Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M. Symbol Value I 1 V 5 X 10 L 50 C 100 D 500 M 1000 For example, 2 is written as II in Roman numeral, just two one's added together. 12 is written as XII, which is simply X + II. The number 27 is written as XXVII, which is XX + V + II. Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used: I can be placed before V (5) and X (10) to make 4 and 9. X can be placed before L (50) and C (100) to make 40 and 90. C can be placed before D (500) and M (1000) to make 400 and 900. Given a roman numeral, convert it to an integer.

DFS class Solution { public: void solve(vector<vector<char>>& board) { if (board.empty()) return; m = board.size(); n = board[0].size(); for (int i = 0; i < m; i++){ for (int j = 0; j < n; j++){ if ((i == 0 || i == m-1 || j == 0 || j == n-1) && board[i][j] == 'O') dfs(board, i, j); } } for (int i = 0; i < m; i++){ for (int j = 0; j < n; j++){ if (board[i][j] == 'O') board[i][j] = 'X'; if (board[i][j] == '$') board[i][j] = 'O'; } } } private: int m; int n; vector<vector<int>> direction{{-1, 0}, {1, 0}, {0, 1}, {0, -1}}; void dfs(vector<vector<char>>& board, int i, int j){ if (i < 0 || i > m-1 || j < 0 || j > n-1) return; if (board[i][j] != 'O') return; board[i][j] = '$'; for (auto dir : direction) dfs(board, i + dir[0], j + dir[1]); } };

130. Surrounded Regions Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'. A region is captured by flipping all 'O's into 'X's in that surrounded region.

DFS class Solution { public: vector<vector<string>> partition(string s) { vector<vector<string>> res; vector<string> path; dfs(s, 0, path, res); return res; } void dfs(string s, int start, vector<string>& path, vector<vector<string>>& res){ if (start == s.size()){ res.push_back(path); return; } for (int i = start; i < s.size(); i++){ if (!isPalindrome(s, start, i)) continue; path.push_back(s.substr(start, i - start+1)); dfs(s, i+1, path, res); path.pop_back(); } } bool isPalindrome(string s, int start, int end){ while (start < end && s[start] == s[end]){ start++; end--; } return start >= end; } };

131. Palindrome Partitioning Given a string s, partition s such that every substring of the partition is a palindrome. Return all possible palindrome partitioning of s. A palindrome string is a string that reads the same backward as forward.

DP class Solution { public: int minCut(string s) { int n = s.size(); if (n == 1) return 0; vector<vector<bool>> isPalindrome(n+1, vector<bool>(n+1, false)); for (int i = n-1; i >= 0; i--) for (int j = i; j < n; j++) isPalindrome[i][j] = (s[i] == s[j]) && ((j - i) < 2 || isPalindrome[i+1][j-1]); vector<int> dp(n+1, -1); for (int i = 0; i <= n; i++) dp[i] = n - 1 - i; for (int i = n-1; i >= 0; i--) for (int j = i; j < n; j++) if (isPalindrome[i][j]) dp[i] = min(dp[i], dp[j+1]+1); return dp[0]; } };

132. Palindrome Partitioning II Given a string s, partition s such that every substring of the partition is a palindrome. Return the minimum cuts needed for a palindrome partitioning of s

Greedy class Solution { public: int minTaps(int n, vector<int>& ranges) { vector<pair<int, int>> l; for (int i = 0; i <= n; i++) l.push_back(make_pair(i - ranges[i], i + ranges[i])); sort(l.begin(), l.end()); int res = 0, i = 0, curr_e = 0, next_e = 0; while (next_e < n){ while (i <= n && l[i].first <= curr_e) next_e = max(next_e, l[i++].second); if (next_e == curr_e) return -1; curr_e = next_e; ++res; } return res; } };

1326. Minimum Number of Taps to Open to Water a Garden There is a one-dimensional garden on the x-axis. The garden starts at the point 0 and ends at the point n. (i.e The length of the garden is n). There are n + 1 taps located at points [0, 1, ..., n] in the garden. Given an integer n and an integer array ranges of length n + 1 where ranges[i] (0-indexed) means the i-th tap can water the area [i - ranges[i], i + ranges[i]] if it was open. Return the minimum number of taps that should be open to water the whole garden, If the garden cannot be watered return -1 Input: n = 5, ranges = [3,4,1,1,0,0] Output: 1

DFS class Solution { public: Node* cloneGraph(Node* node) { if (node == nullptr) return nullptr; unordered_map<Node*, Node*> m; helper(node, m); return m[node]; } Node* helper(Node* node, unordered_map<Node*, Node*>& m){ if (m.find(node) != m.end()) return m[node]; Node * newNode = new Node(node->val); m[node] = newNode; for (auto n : node->neighbors) newNode->neighbors.push_back(helper(n, m)); return newNode; } }; BFS class Solution { public: Node* cloneGraph(Node* node) { if (node == nullptr) return nullptr; unordered_map<Node*, Node*> m; queue<Node*> q{{node}}; Node* newNode = new Node(node->val); m[node] = newNode; while (!q.empty()){ Node* curr = q.front(); q.pop(); for (auto n : curr->neighbors){ if (m.count(n)){ m[curr]->neighbors.push_back(m[n]); } else{ q.push(n); Node* newNode = new Node(n->val); m[curr]->neighbors.push_back(newNode); m[n] = newNode; } } } return m[node]; } };

133. Clone Graph Given a reference of a node in a connected undirected graph. Return a deep copy (clone) of the graph.

Recursive class Solution { public: unordered_map<Node*, Node*> memo; Node* copyRandomList(Node* head) { if (head == nullptr) return nullptr; if (memo.find(head) != memo.end()) return memo[head]; Node *temp = new Node(head->val); memo[head] = temp; temp->next = copyRandomList(head->next); temp->random = copyRandomList(head->random); return temp; } };

138. Copy List with Random Pointer A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. Return a deep copy of the list.

DP class Solution { public: bool wordBreak(string s, vector<string>& wordDict) { unordered_set<string> dict(wordDict.begin(), wordDict.end()); int n = s.size(); bool dp[n+1]; dp[0] = true; for (int i = 1; i <= n; i++){ for (int j = 1; j <= i; j++){ if (dp[i-j] && dict.count(s.substr(i-j, j))){ dp[i] = true; break; } else dp[i] = false; } } return dp[n]; } };

139. Word Break Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

DP class Solution { public: bool wordBreak(string s, vector<string>& wordDict) { unordered_set dict(wordDict.begin(), wordDict.end()); vector<bool> dp(s.size()+1, false); dp[0] = true; for (int i = 1; i <= s.size(); i++){ for(int j = 0; j < i; ++j){ if (dp[j] && dict.count(s.substr(j, i-j))){ dp[i] = true; break; } } } return dp.back(); } };

139. Word Break Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words. Input: s = "leetcode", wordDict = ["leet", "code"] Output: true

Backtracking class Solution { public: vector<string> wordBreak(string s, vector<string>& wordDict) { unordered_map<string, vector<string>> m; return helper(s, wordDict, m); } vector<string> helper(string s, vector<string>& wordDict, unordered_map<string, vector<string>>& m) { if (m.count(s)) return m[s]; if (s.empty()) return {""}; vector<string> res; for (auto w : wordDict){ if (s.substr(0, w.size()) != w) continue; vector<string> temp = helper(s.substr(w.size()), wordDict, m); for (auto t : temp){ res.push_back(w + (t.empty() ? "" : " ") + t); } } m[s] = res; return res; } };

140. Word Break II Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add spaces in s to construct a sentence where each word is a valid dictionary word. Return all such possible sentences.

Slow & fast pointers class Solution { public: bool hasCycle(ListNode *head) { if(head == nullptr) return false; ListNode *slow = head, *fast = head; while (fast && fast->next){ slow = slow->next; fast = fast->next->next; if (slow == fast) return true; } return false; } };

141. Linked List Cycle Given head, the head of a linked list, determine if the linked list has a cycle in it. There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer. Internally, pos is used to denote the index of the node that tail's next pointer is connected to. Note that pos is not passed as a parameter. Return true if there is a cycle in the linked list. Otherwise, return false.

Stack /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: vector<int> preorderTraversal(TreeNode* root) { vector<int> res; stack<TreeNode*> s; TreeNode *p = root; while (!s.empty() || p){ if (p){ s.push(p); res.push_back(p->val); p = p->left; } else{ p = s.top(); s.pop(); p = p->right; } } return res; } };

144. Binary Tree Preorder Traversal

Stack class Solution { public: vector<int> preorderTraversal(TreeNode* root) { vector<int> res; stack<TreeNode*> stk; TreeNode* curr = root; while (stk.size() > 0 || curr){ if (curr){ res.push_back(curr->val); stk.push(curr); curr = curr->left; } else{ curr = stk.top(); stk.pop(); curr = curr->right; } } return res; } };

144. Binary Tree Preorder Traversal

Stack /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: vector<int> postorderTraversal(TreeNode* root) { vector<int> res; stack<TreeNode*> s; TreeNode* p = root; while (!s.empty() || p){ if (p){ s.push(p); res.insert(res.begin(), p->val); p = p->right; } else{ p = s.top(); s.pop(); p = p->left; } } return res; } };

145. Binary Tree Postorder Traversal

Stack class Solution { public: vector<int> postorderTraversal(TreeNode* root) { vector<int> res; stack<TreeNode*> stk; TreeNode *curr = root, *pre = nullptr; while (stk.size() || curr){ if (curr){ stk.push(curr); curr = curr->left; } else{ curr = stk.top(); if (curr->right == nullptr || curr->right == pre){ stk.pop(); res.push_back(curr->val); pre = curr; curr = nullptr; } else{ curr = curr->right; } } } return res; } };

145. Binary Tree Postorder Traversal

Linked List class LRUCache { public: LRUCache(int capacity) { cap = capacity; } int get(int key) { auto map_it = key_it_map.find(key); if (map_it == key_it_map.end()) return -1; key_value_list.splice(key_value_list.begin(), key_value_list, map_it->second); return map_it->second->second; } void put(int key, int value) { auto map_it = key_it_map.find(key); if (map_it != key_it_map.end()) key_value_list.erase(map_it->second); key_value_list.push_front(make_pair(key, value)); key_it_map[key] = key_value_list.begin(); if (key_value_list.size() > cap){ int k = key_value_list.rbegin()->first; key_it_map.erase(k); key_value_list.pop_back(); } } private: int cap; list<pair<int, int>> key_value_list; unordered_map<int, list<pair<int, int>>::iterator> key_it_map; };

146. LRU Cache

Sort /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* insertionSortList(ListNode* head) { ListNode* dummy = new ListNode(-1); while (head){ ListNode* begin = dummy; ListNode* next = head->next; while (begin->next && begin->next->val < head->val) begin = begin->next; head->next = begin->next; begin->next = head; head = next; } return dummy->next; } };

147. Insertion Sort List Sort a linked list using insertion sort.

Insert Sort class Solution { public: ListNode* insertionSortList(ListNode* head) { ListNode *dummy = new ListNode(-1); while (head){ ListNode* curr = dummy; ListNode* temp = head->next; while (curr->next && curr->next->val < head->val) curr = curr->next; head->next = curr->next; curr->next = head; head = temp; } return dummy->next; } };

147. Insertion Sort List Sort a linked list using insertion sort. Input: 4->2->1->3 Output: 1->2->3->4

Merge Sort /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* sortList(ListNode* head) { if (head == nullptr || head->next == nullptr) return head; ListNode *slow = head, *fast = head; while (fast->next && fast->next->next){ slow = slow->next; fast = fast->next->next; } fast = slow; slow = slow->next; fast->next = nullptr; ListNode* l1 = sortList(head); ListNode* l2 = sortList(slow); return merge(l1, l2); } ListNode* merge(ListNode* l1, ListNode* l2){ ListNode *dummy = new ListNode(-1), *p = dummy; for (; l1 && l2; p = p->next){ if (l1->val <= l2->val){ p->next = l1; l1 = l1->next; } else{ p->next = l2; l2 = l2->next; } } if (l1) p->next = l1; if (l2) p->next = l2; return dummy->next; } };

148. Sort List Given the head of a linked list, return the list after sorting it in ascending order.

Merge Sort class Solution { public: ListNode* sortList(ListNode* head) { if (head == nullptr || head->next == nullptr) return head; ListNode *prev = head, *slow = head, *fast = head; while (fast && fast->next){ prev = slow; slow = slow->next; fast = fast->next->next; } prev->next = nullptr; ListNode *l1 = sortList(head); ListNode *l2 = sortList(slow); return merge(l1, l2); } ListNode* merge(ListNode* l1, ListNode* l2){ ListNode *head = new ListNode(-1), *curr = head; if (l1 == nullptr) return l2; if (l2 == nullptr) return l1; while (l1 && l2){ if (l1->val < l2->val){ curr->next = l1; l1 = l1->next; } else{ curr->next = l2; l2 = l2->next; } curr = curr->next; } if (l1 == nullptr) curr->next = l2; if (l2 == nullptr) curr->next = l1; return head->next; } };

148. Sort List Given the head of a linked list, return the list after sorting it in ascending order.

Heap class Solution { public: int maxPoints(vector<vector<int>>& points) { int n = points.size(); int res = 0; for (int i = 0; i < n; i++){ map<pair<int, int>, int> tree_map; int duplicate = 1; for (int j = i+1; j < n; j++){ if (points[i][0] == points[j][0] && points[i][1] == points[j][1]) duplicate++; else{ int dx = points[i][0] - points[j][0]; int dy = points[i][1] - points[j][1]; int d = gcd(dx, dy); tree_map[{dx/d, dy/d}]++; } } res = max(res, duplicate); for (auto m : tree_map) res = max(res, m.second+duplicate); } return res; } int gcd(int a, int b){ return b == 0 ? a : gcd(b, a%b); } };

149. Max Points on a Line Given an array of points where points[i] = [xi, yi] represents a point on the X-Y plane, return the maximum number of points that lie on the same straight line.

Tree Map class Solution { public: int maxPoints(vector<vector<int>>& points) { int n = points.size(); int res = 0; for (int i = 0; i < n; i++){ int duplicate = 1; map<pair<int, int>, int> m; for (int j = i+1; j < n; j++){ if (points[i][0] == points[j][0] && points[i][1] == points[j][1]){ duplicate++; continue; } int dx = points[i][0] - points[j][0]; int dy = points[i][1] - points[j][1]; int d = gcd(dx, dy); ++m[{dx/d, dy/d}]; } res = max(res, duplicate); for (auto x : m) res = max(res, x.second + duplicate); } return res; } int gcd(int a, int b){ return (b == 0)? a : gcd(b, a%b); } };

149. Max Points on a Line Given an array of points where points[i] = [xi, yi] represents a point on the X-Y plane, return the maximum number of points that lie on the same straight line. Input: points = [[1,1],[2,2],[3,3]] Output: 3

Two Pointers class Solution { public: vector<vector<int>> threeSum(vector<int>& nums) { int n = nums.size(); vector<vector<int>> res; sort(nums.begin(), nums.end()); for (int i = 0; i < n-2; i++){ if (i>0 && nums[i]==nums[i-1]) continue; int p1 = i+1, p2 = n-1; while (p1 < p2){ int temp = nums[p1]+nums[p2]; if (temp >-nums[i]) p2--; else if (temp < -nums[i]) p1++; else{ res.push_back({nums[i], nums[p1], nums[p2]}); p1++; p2--; while (p1<p2 && nums[p1] == nums[p1-1]) p1++; while (p1<p2 && nums[p2] == nums[p2+1]) p2--; } } } return res; } };

15. 3Sum Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. Note: The solution set must not contain duplicate triplets. Example: Given array nums = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]

Stack class Solution { public: int evalRPN(vector<string>& tokens) { int res = 0; if (tokens.size() == 0) return res; stack<int> stk; for (int i = 0; i < tokens.size(); i++){ if (tokens[i] != "+" && tokens[i] != "-" && tokens[i] != "*" && tokens[i] != "/") stk.push(stoi(tokens[i])); else{ int num1 = stk.top(); stk.pop(); int num2 = stk.top(); stk.pop(); if (tokens[i] == "+") stk.push(num2 + num1); if (tokens[i] == "-") stk.push(num2 - num1); if (tokens[i] == "*") stk.push(num2 * num1); if (tokens[i] == "/") stk.push(num2 / num1); } } return stk.top(); } };

150. Evaluate Reverse Polish Notation Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, *, /. Each operand may be an integer or another expression.

Stack class Solution { public: int evalRPN(vector<string>& tokens) { stack<int> s; for (auto c : tokens){ if (c != "+" && c != "-" && c != "*" && c != "/") s.push(stoi(c)); else{ int num1 = s.top(); s.pop(); int num2 = s.top(); s.pop(); if (c == "+") s.push(num2 + num1); if (c == "-") s.push(num2 - num1); if (c == "*") s.push(num2 * num1); if (c == "/") s.push(num2 / num1); } } return s.top(); } };

150. Evaluate Reverse Polish Notation Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, *, /. Each operand may be an integer or another expression.

One Pass class Solution { public: string reverseWords(string s) { reverse(s.begin(), s.end()); int curr = 0; for (int i = 0; i < s.size(); i++){ if (s[i] == ' ') continue; if (curr != 0) s[curr++] = ' '; int j = i; while (j < s.size() && s[j] != ' ') s[curr++] = s[j++]; reverse(s.begin() + curr - (j-i), s.begin()+curr); i = j; } s.resize(curr); return s; } };

151. Reverse Words in a String Given an input string s, reverse the order of the words. A word is defined as a sequence of non-space characters. The words in s will be separated by at least one space. Return a string of the words in reverse order concatenated by a single space.

DP class Solution { public: int minCost(int n, vector<int>& cuts) { cuts.push_back(n); cuts.push_back(0); sort(cuts.begin(), cuts.end()); int m = cuts.size(); vector<vector<int>> dp(m, vector<int>(m, 0)); for (int len = 2; len < m; len++){ for (int i = 0; i < m; i++){ int j = i + len; if (j >= m) continue; if (len == 2) dp[i][j] = cuts[j] - cuts[i]; else{ int temp = INT_MAX; for (int k = i+1; k < j; k++) temp = min(temp, dp[i][k] + dp[k][j] + cuts[j] - cuts[i]); dp[i][j] = temp; } } } return dp[0][m-1]; } };

1547. Minimum Cost to Cut a Stick Given a wooden stick of length n units. The stick is labelled from 0 to n. For example, a stick of length 6 is labelled as follows: Given an integer array cuts where cuts[i] denotes a position you should perform a cut at. You should perform the cuts in order, you can change the order of the cuts as you wish. The cost of one cut is the length of the stick to be cut, the total cost is the sum of costs of all cuts. When you cut a stick, it will be split into two smaller sticks (i.e. the sum of their lengths is the length of the stick before the cut). Please refer to the first example for a better explanation. Return the minimum total cost of the cuts.

Stack class MinStack { public: /** initialize your data structure here. */ stack<int> s1, s2; MinStack() { } void push(int x) { s1.push(x); if (s2.empty()) s2.push(x); else s2.push(min(x, s2.top())); } void pop() { s1.pop(); s2.pop(); } int top() { return s1.top(); } int getMin() { return s2.top(); } };

155. Min Stack Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. push(x) -- Push element x onto stack. pop() -- Removes the element on top of the stack. top() -- Get the top element. getMin() -- Retrieve the minimum element in the stack.

Two pointers class Solution { public: int threeSumClosest(vector<int>& nums, int target) { int diff = INT_MAX, n = nums.size(), res = INT_MAX; sort(nums.begin(), nums.end()); for (int i = 0; i < n; i++){ int p1 = i+1, p2 = n-1; while (p1 < p2){ int temp = nums[i] + nums[p1] + nums[p2]; if (temp == target) return target; if (temp > target) p2--; else p1++; if (abs(temp-target) < diff){ diff = abs(temp-target); res = temp; } } } return res; } };

16. 3Sum Closest Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

Cycle detection class Solution { public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { ListNode *p1 = headA, *p2 = headB; while (p1 || p2){ if (p1 == p2) return p1; if (p1 == nullptr) p1 = headB; else p1 = p1->next; if (p2 == nullptr) p2 = headA; else p2 = p2->next; } return nullptr; } };

160. Intersection of Two Linked Lists Write a program to find the node at which the intersection of two singly linked lists begins.

One Pass class Solution { public: bool isOneEditDistance(string s, string t) { int m = s.size(), n = t.size(); for (int i = 0; i < min(m, n); i++){ if (s[i] == t[i]) continue; if (m == n) return s.substr(i+1) == t.substr(i+1); if (m < n) return s.substr(i) == t.substr(i+1); else return s.substr(i+1) == t.substr(i); } return abs(m-n) == 1; } };

161. One Edit Distance Given two strings s and t, return true if they are both one edit distance apart, otherwise return false. A string s is said to be one distance apart from a string t if you can: Insert exactly one character into s to get t. Delete exactly one character from s to get t. Replace exactly one character of s with a different character to get t.

Two Pointers class Solution { public: vector<int> twoSum(vector<int>& numbers, int target) { int p1 = 0, p2 = numbers.size() - 1; vector<int> res(2, -1); while (p1 < p2) { int temp = numbers[p1] + numbers[p2]; if (temp > target){ p2--; } else if (temp < target){ p1++; } else{ res[0] = p1+1; res[1] = p2+1; return res; } } return res; } };

167. Two Sum II - Input array is sorted Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number. The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Input: numbers = [2,7,11,15], target = 9 Output: [1,2] Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2.

Backtracking class Solution { public: vector<string> letterCombinations(string digits) { vector<string> res; if (!digits.empty()) backtrack(digits, 0, "", res); return res; } private: vector<string> keyboard{"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; void backtrack(string digits, int level, string path, vector<string>& res){ if (level == digits.size()){ res.push_back(path); return; } for (auto c : keyboard[digits[level] - '0']) backtrack(digits, level + 1, path + c, res); } };

17. Letter Combinations of a Phone Number

Slow & fast pointers class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode* temp = new ListNode(); temp->next = head; ListNode* slow = temp, *fast = temp; for(int i = 0; i < n; i++) fast = fast->next; while(fast->next != nullptr){ slow = slow->next; fast = fast->next; } slow->next = slow->next->next; return temp->next; } };

19. Remove Nth Node From End of List Given the head of a linked list, remove the nth node from the end of the list and return its head.

Bit class Solution { public: uint32_t reverseBits(uint32_t n) { uint32_t res = 0; for (int i = 0; i < 32; i++){ if (n & 1 == 1) res = (res << 1) + 1; else res = res << 1; n = n >> 1; } return res; } };

190. Reverse Bits Reverse bits of a given 32 bits unsigned integer.

Bit class Solution { public: int hammingWeight(uint32_t n) { int res = 0; for (int i = 0; i < 32; i++){ if (n&1 == 1) res++; n = n>>1; } return res; } };

191. Number of 1 Bits Write a function that takes an unsigned integer and returns the number of '1' bits it has (also known as the Hamming weight).

DP class Solution { public: int rob(vector<int>& nums) { if (nums.size() < 2) return nums.empty() ? 0 : nums[0]; vector<int> dp(nums.size(), 0); dp[0] = nums[0]; dp[1] = max(nums[0], nums[1]); for (int i = 2; i < nums.size(); ++i) dp[i] = max(dp[i-1], dp[i-2] + nums[i]); return dp[nums.size()-1]; } };

198. House Robber You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night. Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

Queue class Solution { public: vector<int> rightSideView(TreeNode* root) { vector<int> res; if (root == nullptr) return res; queue<TreeNode*> que; que.push(root); while (que.size()){ res.push_back(que.back()->val); int len = que.size(); for (int i = 0; i < len; i++){ TreeNode *node = que.front(); que.pop(); if (node->left) que.push(node->left); if (node->right) que.push(node->right); } } return res; } };

199. Binary Tree Right Side View Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.

Linked List class Solution { public: ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { ListNode *dummy = new ListNode(-1), *curr = dummy; int carry = 0; while (l1 || l2 || carry){ int temp = (l1 ? l1->val : 0) + (l2 ? l2->val : 0) + carry; carry = temp / 10; curr->next = new ListNode(temp%10); curr = curr->next; l1 = l1 ? l1->next : nullptr; l2 = l2 ? l2->next : nullptr; } return dummy->next; } };

2. Add Two Numbers You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the two numbers and return the sum as a linked list. You may assume the two numbers do not contain any leading zero, except the number 0 itself. Input: l1 = [2,4,3], l2 = [5,6,4] Output: [7,0,8] Explanation: 342 + 465 = 807.

Stack class Solution { public: bool isValid(string s) { string left = "({["; string right = ")}]"; stack<char> stk; for (auto c : s){ if (left.find(c) != string::npos){ stk.push(c); } else{ if (stk.empty() || stk.top() != left[right.find(c)]) return false; stk.pop(); } } return stk.empty(); } };

20. Valid Parentheses Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.

Stack class Solution { public: bool isValid(string s) { if (s.size() < 2) return false; stack<char> res; for (int i = 0; i < s.size(); i++) { if (s[i] == '(' || s[i] == '[' || s[i] == '{') res.push(s[i]); else if (res.empty() || (s[i] == ')' && res.top() != '(') || (s[i] == ']' && res.top() != '[') || (s[i] == '}' && res.top() != '{')) return false; else res.pop(); } return res.empty(); } };

20. Valid Parentheses Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. An input string is valid if: Open brackets must be closed by the same type of brackets. Open brackets must be closed in the correct order.

Trie class Solution { public: bool isHappy(int n) { int slow = n; int fast = squareSum(n); while (slow != fast){ if (slow == 1 || fast == 1) return true; slow = squareSum(slow); fast = squareSum(squareSum(fast)); } return slow == 1; } int squareSum(int n){ int res = 0; while (n > 0){ res += (n%10) * (n%10); n /= 10; } return res; } };

202. Happy Number Write an algorithm to determine if a number n is happy. A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits. Repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy. Return true if n is a happy number, and false if not.

Linked List class Solution { public: ListNode* removeElements(ListNode* head, int val) { while (head && head->val == val) head = head->next; if (head == nullptr) return head; ListNode *curr = head->next, *prev = head; while (curr){ if (curr->val == val) prev->next = curr->next; else prev = curr; curr = curr->next; } return head; } };

203. Remove Linked List Elements Remove all elements from a linked list of integers that have value val.

Hashmap class Solution { public: bool isIsomorphic(string s, string t) { unordered_map<char, int> hash1; unordered_map<char, int> hash2; for (int i = 0; i < s.size(); i++){ if (hash1.find(s[i]) != hash1.end() || hash2.find(t[i]) != hash2.end()){ if (hash1[s[i]] != hash2[t[i]]) return false; } else{ hash1[s[i]] = i+1; hash2[t[i]] = i+1; } } return true; } };

205. Isomorphic Strings Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the characters in s can be replaced to get t. All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character but a character may map to itself Input: s = "egg", t = "add" Output: true

Recursive class Solution { public: ListNode* reverseList(ListNode* head) { if (head == nullptr || head->next == nullptr) return head; ListNode *p = reverseList(head->next); head->next->next = head; head->next = nullptr; return p; } };

206. Reverse Linked List

Trie class TrieNode{ public: TrieNode *child[26]; bool isWord; TrieNode() : isWord{false}{ for (int i = 0; i < 26; i++) child[i] = nullptr; } }; class Trie { public: /** Initialize your data structure here. */ Trie() { root = new TrieNode(); } /** Inserts a word into the trie. */ void insert(string word) { TrieNode *p = root; for (auto w : word){ int i = w-'a'; if (!p->child[i]) p->child[i] = new TrieNode(); p = p->child[i]; } p->isWord = true; } /** Returns if the word is in the trie. */ bool search(string word) { TrieNode *p = root; for (auto w : word){ int i = w-'a'; if (!p->child[i]) return false; p = p->child[i]; } return p->isWord; } /** Returns if there is any word in the trie that starts with the given prefix. */ bool startsWith(string prefix) { TrieNode *p = root; for (auto w : prefix){ int i = w-'a'; if (!p->child[i]) return false; p = p->child[i]; } return true; } private: TrieNode* root; };

208. Implement Trie (Prefix Tree)

Linked List class Solution { public: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { ListNode *head = new ListNode(-1), *curr = head; if (l1 == nullptr) return l2; if (l2 == nullptr) return l1; while (l1 && l2){ if (l1->val < l2->val){ curr->next = l1; l1 = l1->next; } else{ curr->next = l2; l2 = l2->next; } curr = curr->next; } if (l1 == nullptr) curr->next = l2; if (l2 == nullptr) curr->next = l1; return head->next; } };

21. Merge Two Sorted Lists Merge two sorted linked lists and return it as a new sorted list. The new list should be made by splicing together the nodes of the first two lists.

Sort /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { if (l1 == nullptr) return l2; if (l2 == nullptr) return l1; ListNode *dummy = new ListNode(-1), *p = dummy; while (l1 != nullptr && l2 != nullptr){ if (l1->val <= l2->val){ p->next = l1; l1 = l1->next; } else{ p->next = l2; l2 = l2->next; } p = p->next; } p->next = l1 != nullptr ? l1 : l2; return dummy->next; } };

21. Merge Two Sorted Lists Merge two sorted linked lists and return it as a sorted list. The list should be made by splicing together the nodes of the first two lists.

Topological Sort class Solution { public: vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) { unordered_map<int, vector<int>> graph; vector<int> indegree(numCourses, 0), res; queue<int> q; for (auto p : prerequisites){ graph[p[1]].push_back(p[0]); indegree[p[0]]++; } for (int i = 0; i < numCourses; i++) if (indegree[i] == 0) q.push(i); while (!q.empty()){ int len = q.size(); for (int i = 0; i < len; i++){ int curr = q.front(); q.pop(); res.push_back(curr); for (auto g : graph[curr]) if (--indegree[g] == 0) q.push(g); } } return res.size() == numCourses ? res : vector<int>{}; } };

210. Course Schedule II There are a total of n courses you have to take labelled from 0 to n - 1. Some courses may have prerequisites, for example, if prerequisites[i] = [ai, bi] this means you must take the course bi before the course ai. Given the total number of courses numCourses and a list of the prerequisite pairs, return the ordering of courses you should take to finish all courses. If there are many valid answers, return any of them. If it is impossible to finish all courses, return an empty array. Input: numCourses = 2, prerequisites = [[1,0]] Output: [0,1]

Fast & slow pointers, Recursive class Solution { public: bool isPalindrome(ListNode* head) { if(head == nullptr || head->next == nullptr) return true; ListNode *slow = head, *fast = head; while (fast->next && fast->next->next){ slow = slow->next; fast = fast->next->next; } ListNode *p = reverse(slow->next); while (p){ if (p->val != head->val) return false; p = p->next; head = head->next; } return true; } ListNode* reverse(ListNode* head){ if (head == nullptr || head->next == nullptr) return head; ListNode* p = reverse(head->next); head->next->next = head; head->next = nullptr; return p; } };

234. Palindrome Linked List Given a singly linked list, determine if it is a palindrome.

Recursive class Solution { public: TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { if (p->val < root->val && q->val < root->val) return lowestCommonAncestor(root->left, p, q); if (p->val > root->val && q->val > root->val) return lowestCommonAncestor(root->right, p, q); return root; } };

235. Lowest Common Ancestor of a Binary Search Tree

Trie class TrieNode{ public: TrieNode* child[26]; bool isWord; TrieNode() : isWord{false}{ for (auto &c : child) c = nullptr; } }; class WordDictionary { public: /** Initialize your data structure here. */ WordDictionary() { root = new TrieNode(); } void addWord(string word) { TrieNode* p = root; for (auto c : word){ int i = c-'a'; if (!p->child[i]) p->child[i] = new TrieNode(); p = p->child[i]; } p->isWord = true; } bool helper(string word, TrieNode* &curr){ if (word.size() == 0) return word[0] == '.' || curr->isWord; if (word[0] != '.'){ if (curr->child[word[0]-'a'] == nullptr) return false; return helper(word.substr(1, word.size()-1), curr->child[word[0]-'a']); } else{ for (auto &c : curr->child){ if (c == nullptr) continue; if (helper(word.substr(1, word.size()-1), c)) return true; } return false; } } bool search(string word) { return helper(word, root); } private: TrieNode* root; };

211. Design Add and Search Words Data Structure Design a data structure that supports adding new words and finding if a string matches any previously added string. Implement the WordDictionary class: WordDictionary() Initializes the object. void addWord(word) Adds word to the data structure, it can be matched later. bool search(word) Returns true if there is any string in the data structure that matches word or false otherwise. word may contain dots '.' where dots can be matched with any letter.

Quick Sort class Solution { public: int findKthLargest(vector<int>& nums, int k) { int left = 0, right = nums.size()-1; while (true){ int pos = partition(nums, left, right); if (pos == k-1) return nums[pos]; if (pos > k-1) right = pos-1; else left = pos+1; } } int partition(vector<int>& nums, int left, int right){ int pivot = nums[left], l = left+1, r = right; while (l <= r){ if (nums[l] < pivot && nums[r] > pivot) swap(nums[l++], nums[r--]); if (nums[l] >= pivot) l++; if (nums[r] <= pivot) r--; } swap(nums[left], nums[r]); return r; } };

215. Kth Largest Element in an Arra Given an integer array nums and an integer k, return the kth largest element in the array. Note that it is the kth largest element in the sorted order, not the kth distinct element. Input: nums = [3,2,1,5,6,4], k = 2 Output: 5

Hashmap class Solution { public: bool containsDuplicate(vector<int>& nums) { unordered_map<int, int> hash; for (int i = 0; i < nums.size(); i++){ if (hash.find(nums[i]) != hash.end()) return true; else hash[nums[i]] = i; } return false; } }; Hashset class Solution { public: bool containsDuplicate(vector<int>& nums) { unordered_set<int> s(nums.begin(), nums.end()); return nums.size() > s.size(); } };

217. Contains Duplicate Given an array of integers, find if the array contains any duplicates.

DFS class Solution { public: vector<string> generateParenthesis(int n) { vector<string> res; string path; dfs(n, 0, 0, path, res); return res; } void dfs(int n, int l, int r, string& path, vector<string>& res){ if (l == n){ string temp(path); res.push_back(temp.append(n-r, ')')); return; } path.push_back('('); dfs(n, l+1, r, path, res); path.pop_back(); if (l > r){ path.push_back(')'); dfs(n, l, r+1, path, res); path.pop_back(); } } };

22. Generate Parentheses Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

DP class Solution { public: int maximalSquare(vector<vector<char>>& matrix) { int res = 0; if (matrix.empty() || matrix[0].empty()) return res; int m = matrix.size(), n = matrix[0].size(); vector<vector<int>> dp(m, vector<int>(n, 0)); for (int i = 0; i < m; ++i){ for (int j = 0; j < n; ++j){ if (i == 0 || j == 0) dp[i][j] = (matrix[i][j] == '1') ? 1 : 0; else if (matrix[i][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; } };

221. Maximal Square Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area.

Queue class MyStack { public: /** Initialize your data structure here. */ queue<int> q; MyStack() { } /** Push element x onto stack. */ void push(int x) { q.push(x); for (int i = 0; i < q.size()-1; i++){ q.push(q.front()); q.pop(); } } /** Removes the element on top of the stack and returns that element. */ int pop() { int temp = q.front(); q.pop(); return temp; } /** Get the top element. */ int top() { return q.front(); } /** Returns whether the stack is empty. */ bool empty() { return q.empty(); } };

225. Implement Stack using Queues

Recursive class Solution { public: TreeNode* invertTree(TreeNode* root) { if (root) { invertTree(root->left); invertTree(root->right); swap(root->left, root->right); } return root; } };

226. Invert Binary Tree

Heap class Solution { public: ListNode* mergeKLists(vector<ListNode*>& lists) { struct cmp{ bool operator()(ListNode* &a, ListNode* &b){ return a->val > b->val; } }; priority_queue<ListNode*, vector<ListNode*>, cmp> q; for (auto l : lists) if (l) q.push(l); ListNode *dummy = new ListNode(-1), *p = dummy; while (!q.empty()){ ListNode* temp = q.top(); q.pop(); p->next = temp; p = p->next; if (p->next) q.push(p->next); } return dummy->next; } };

23. Merge k Sorted Lists

Min Heap /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* mergeKLists(vector<ListNode*>& lists) { struct cmp{ bool operator()(ListNode* &a, ListNode* &b){ return a->val > b->val; } }; priority_queue<ListNode*, vector<ListNode*>, cmp> q; for (auto l : lists) if (l) q.push(l); ListNode *dummy = new ListNode(-1), *p = dummy; while (!q.empty()){ ListNode* temp = q.top(); q.pop(); p->next = temp; p = p->next; if (p->next) q.push(p->next); } return dummy->next; } };

23. Merge k Sorted Lists You are given an array of k linked-lists lists, each linked-list is sorted in ascending order. Merge all the linked-lists into one sorted linked-list and return it.

Stack class Solution { public: int kthSmallest(TreeNode* root, int k) { if (root == nullptr) return 0; stack<TreeNode*> stk; TreeNode* curr = root; while (curr || stk.size()){ if (curr){ stk.push(curr); curr = curr->left; } else{ curr = stk.top(); stk.pop(); if (--k == 0) break; curr = curr->right; } } return curr->val; } };

230. Kth Smallest Element in a BST

Recursive class Solution { public: TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { if (root == nullptr || root == q || root == p) return root; TreeNode* left = lowestCommonAncestor(root->left, p, q); TreeNode* right = lowestCommonAncestor(root->right, p, q); if (left&&right) return root; return left ? left:right; } };

236. Lowest Common Ancestor of a Binary Tree

Left & Right class Solution { public: vector<int> productExceptSelf(vector<int>& nums) { int n = nums.size(); vector<int> left(n, 1), right(n, 1); for (int i = 1; i < n; i++) left[i] = left[i-1] * nums[i-1]; for (int j = n-2; j >= 0; j--) right[j] = right[j+1] * nums[j+1]; for (int i = 0; i < n; i++) nums[i] = left[i] * right[i]; return nums; } };

238. Product of Array Except Self Given an array nums of n integers where n > 1, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i]. Input: [1,2,3,4] Output: [24,12,8,6]

Linked List class Solution { public: ListNode* swapPairs(ListNode* head) { ListNode *dummy = new ListNode(-1); dummy->next = head; ListNode *pre = dummy, *cur = head; while(cur &&cur->next){ pre->next = cur->next; cur->next = cur->next->next; pre->next->next = cur; pre = cur; cur = cur->next; } return dummy->next; } };

24. Swap Nodes in Pairs Given a linked list, swap every two adjacent nodes and return its head. You may not modify the values in the list's nodes. Only nodes itself may be changed. Input: head = [1,2,3,4] Output: [2,1,4,3]

Hashmap class Solution { public: bool isAnagram(string s, string t) { sort(s.begin(), s.end()); sort(t.begin(), t.end()); return s==t; } };

242. Valid Anagram Given two strings s and t, return true if t is an anagram of s, and false otherwise.

Stack class Solution { public: int strobogrammaticInRange(string low, string high) { int res = 0; helper(low, high, "", res); helper(low, high, "0", res); helper(low, high, "1", res); helper(low, high, "8", res); return res; } void helper(string low, string high, string path, int &res){ if (path.size() >= low.size() && path.size() <= high.size()){ if (path.size() == high.size() && path.compare(high) > 0) return; if (!(path.size() > 1 && path[0] == '0') && !(path.size() == low.size() && path.compare(low) < 0)) ++res; } if (path.size()+2 > high.size()) return; helper(low, high, "0" + path + "0", res); helper(low, high, "1" + path + "1", res); helper(low, high, "6" + path + "9", res); helper(low, high, "7" + path + "8", res); helper(low, high, "9" + path + "6", res); } };

248. Strobogrammatic Number III Given two strings low and high that represent two integers low and high where low <= high, return the number of strobogrammatic numbers in the range [low, high]. A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down). Input: low = "50", high = "100" Output: 3

Recursion class Solution { public: ListNode* reverseList(ListNode* head, ListNode* tail){ if (head->next == tail) return head; ListNode* temp = reverseList(head->next, tail); head->next->next = head; head->next = tail; return temp; } ListNode* reverseKGroup(ListNode* head, int k) { ListNode* curr = head; for (int i = 0; i < k; i++){ if (curr == nullptr) return head; curr = curr->next; } ListNode* new_head = reverseList(head, curr); head->next = reverseKGroup(curr, k); return new_head; } };

25. Reverse Nodes in k-Group Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes, in the end, should remain as it is.

DFS class Solution { public: int minMeetingRooms(vector<vector<int>>& intervals) { sort(intervals.begin(), intervals.end(), [](const vector<int>& a, const vector<int>& b){return a[0] < b[0];}); priority_queue<int, vector<int>, greater<int>> min_heap; for (auto i : intervals){ if (min_heap.size() > 0 && i[0] >= min_heap.top()) min_heap.pop(); min_heap.push(i[1]); } return min_heap.size(); } };

253. Meeting Rooms II Given an array of meeting time intervals intervals where intervals[i] = [starti, endi], return the minimum number of conference rooms required. Input: intervals = [[0,30],[5,10],[15,20]] Output: 2

Backtracking class Solution { public: vector<string> binaryTreePaths(TreeNode* root) { vector<string> res; if (root == nullptr) return res; backtrack(root, res, ""); return res; } void backtrack(TreeNode* root, vector<string>& res, string path){ if (root->left == nullptr && root->right == nullptr) res.push_back(path + to_string(root->val)); string temp = path; path += to_string(root->val) + "->"; if (root->left) backtrack(root->left, res, path); if (root->right) backtrack(root->right, res, path); path = temp; } };

257. Binary Tree Paths Given a binary tree, return all root-to-leaf paths. Note: A leaf is a node with no children

Fast&Slow Pointers class Solution { public: int removeDuplicates(vector<int>& nums) { if (nums.size() <= 1) return nums.size(); int slow = 1, fast = 1; while (fast < nums.size()){ if (nums[fast] != nums[slow-1]) nums[slow++] = nums[fast]; fast++; } return slow; } };

26. Remove Duplicates from Sorted Array Given a sorted array nums, remove the duplicates in-place such that each element appear only once and return the new length. Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory. Example 1: Given nums = [1,1,2], Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the returned length.

One pass class Solution { public: int missingNumber(vector<int>& nums) { int n = nums.size(), i = 0; while (i < n){ if (nums[i] < n && nums[i] != nums[nums[i]]) swap(nums[i], nums[nums[i]]); else i++; } for (int i = 0; i < n; i++) if (nums[i] != i) return i; return n; } };

268. Missing Number Given an array nums containing n distinct numbers in the range [0, n], return the only number in the range that is missing from the array. Input: nums = [3,0,1] Output: 2

MIN/MAX stack class MedianFinder { public: /** initialize your data structure here. */ MedianFinder() { } void addNum(int num) { if (max_heap.empty() || num <= max_heap.top()) max_heap.push(num); else min_heap.push(num); int diff = max_heap.size() - min_heap.size(); if (diff > 1){ min_heap.push(max_heap.top()); max_heap.pop(); } else if (diff < 0){ max_heap.push(min_heap.top()); min_heap.pop(); cout << 1 << endl; } } double findMedian() { if (max_heap.size() == min_heap.size()) return 0.5 * (min_heap.top() + max_heap.top()); return max_heap.top(); } private: priority_queue<int> max_heap; priority_queue<int, vector<int>, greater<int>> min_heap; };

295. Find Median from Data Stream Implement the MedianFinder class: MedianFinder() initializes the MedianFinder object. void addNum(int num) adds the integer num from the data stream to the data structure. double findMedian() returns the median of all elements so far. Answers within 10-5 of the actual answer will be accepted.

Topological Sort class Solution { public: string alienOrder(vector<string>& words) { unordered_map<char, vector<char>> map; unordered_map<char, int> indegree; unordered_set<char> dict; queue<char> q; string res; for (auto w : words) dict.insert(w.begin(), w.end()); for (int i = 0; i < words.size()-1; i++){ int len = min(words[i].size(), words[i+1].size()), j = 0; for (; j < len; j++){ if (words[i][j] != words[i+1][j]){ map[words[i][j]].push_back(words[i+1][j]); indegree[words[i+1][j]]++; break; } } if (j == len && words[i].size() > words[i+1].size()) return ""; } for (auto c : dict){ if (indegree.find(c) == indegree.end()){ q.push(c); res += c; } } while (!q.empty()){ char c = q.front(); q.pop(); for (auto child : map[c]){ if (--indegree[child] == 0){ q.push(child); res += child; } } } return res.size() == dict.size() ? res : ""; } };

269. Alien Dictionary There is a new alien language that uses the English alphabet. However, the order among the letters is unknown to you. You are given a list of strings words from the alien language's dictionary, where the strings in words are sorted lexicographically by the rules of this new language. Return a string of the unique letters in the new alien language sorted in lexicographically increasing order by the new language's rules. If there is no solution, return "". If there are multiple solutions, return any of them. A string s is lexicographically smaller than a string t if at the first letter where they differ, the letter in s comes before the letter in t in the alien language. If the first min(s.length, t.length) letters are the same, then s is smaller if and only if s.length < t.length. Input: words = ["wrt","wrf","er","ett","rftt"] Output: "wertf"

Fast&Slow Pointers class Solution { public: int removeElement(vector<int>& nums, int val) { int slow = 0, fast = 0; while (fast < nums.size()){ if (nums[fast] != val) nums[slow++] = nums[fast]; fast++; } return slow; } };

27. Remove Element Given an array nums and a value val, remove all instances of that value in-place and return the new length. Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory. The order of elements can be changed. It doesn't matter what you leave beyond the new length.

Fast&Slow Pointers class Solution { public: int removeElement(vector<int>& nums, int val) { int slow = 0, fast = 0; while (fast < nums.size()){ if (nums[fast] != val) nums[slow++] = nums[fast]; fast++; } return slow; } };

27. Remove Element Given an array nums and a value val, remove all instances of that value in-place and return the new length. Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory. The order of elements can be changed. It doesn't matter what you leave beyond the new length. Example 1: Given nums = [3,2,2,3], val = 3, Your function should return length = 2, with the first two elements of nums being 2. It doesn't matter what you leave beyond the returned length.

DP class Solution { public: int numSquares(int n) { vector<int> dp(n+1, INT_MAX); dp[0] = 0; for (int i = 1; i <= n; ++i){ for (int j = 1; j*j <= i; ++j){ dp[i] = min(dp[i], dp[i-j*j] + 1); } } return dp[n]; } };

279. Perfect Squares Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n.

Queue class ZigzagIterator { public: ZigzagIterator(vector<int>& v1, vector<int>& v2) { if (!v1.empty()) q.push({v1.begin(), v1.end()}); if (!v2.empty()) q.push({v2.begin(), v2.end()}); } int next() { auto it = q.front(); q.pop(); if (it.first+1 != it.second) q.push({it.first+1, it.second}); return *it.first; } bool hasNext() { return !q.empty(); } private: queue<pair<vector<int>::iterator, vector<int>::iterator>> q; };

281. Zigzag Iterator Given two vectors of integers v1 and v2, implement an iterator to return their elements alternately. Implement the ZigzagIterator class: ZigzagIterator(List<int> v1, List<int> v2) initializes the object with the two vectors v1 and v2. boolean hasNext() returns true if the iterator still has elements, and false otherwise. int next() returns the current element of the iterator and moves the iterator to the next element.

DP class PeekingIterator : public Iterator { public: PeekingIterator(const vector<int>& nums) : Iterator(nums) { // Initialize any member here. // **DO NOT** save a copy of nums and manipulate it directly. // You should only use the Iterator interface methods. is_next = false; } // Returns the next element in the iteration without advancing the iterator. int peek() { if (!is_next) next_val = Iterator::next(); is_next = true; return next_val; } // hasNext() and next() should behave the same as in the Iterator interface. // Override them if needed. int next() { if (!is_next) next_val = Iterator::next(); is_next = false; return next_val; } bool hasNext() const { return (is_next || Iterator::hasNext()); } private: bool is_next; int next_val; };

284. Peeking Iterator Design an iterator that supports the peek operation on a list in addition to the hasNext and the next operations. Implement the PeekingIterator class: PeekingIterator(int[] nums) Initializes the object with the given integer array nums. int next() Returns the next element in the array and moves the pointer to the next element. bool hasNext() Returns true if there are still elements in the array. int peek() Returns the next element in the array without moving the pointer.

Fast&Slow Pointers class Solution { public: int findDuplicate(vector<int>& nums) { int p = 0; while (p < nums.size()){ while (nums[p] != (p+1)){ if (nums[p] == nums[nums[p]-1]) return nums[p]; swap(nums[p], nums[nums[p]-1]); } p++; } return -1; } };

287. Find the Duplicate Number Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one. Example 1: Input: [1,3,4,2,2] Output: 2

Hashmap class Solution { public: bool wordPattern(string pattern, string s) { unordered_map<char, int> hash1; unordered_map<string, int> hash2; istringstream in(s); int i = 0; for (string word; in >> word; i++){ if (hash1.find(pattern[i]) != hash1.end() || hash2.find(word) != hash2.end()){ if (hash1[pattern[i]] != hash2[word]) return false; } else{ hash1[pattern[i]] = i+1; hash2[word] = i+1; } } return i == pattern.size(); } };

290. Word Pattern Given a pattern and a string s, find if s follows the same pattern. Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in s. Input: pattern = "abba", s = "dog cat cat dog" Output: true

Sliding Window class Solution { public: int lengthOfLongestSubstring(string s) { int n = s.size(), p1 = 0; unordered_set<char> hashset; int res = 0; for (int p2 = 0; p2 < n; p2++){ while (hashset.find(s[p2]) != hashset.end()) hashset.erase(s[p1++]); hashset.insert(s[p2]); res = max(res, p2-p1+1); } return res; } };

3. Longest Substring Without Repeating Characters Given a string s, find the length of the longest substring without repeating characters.

DP class Solution { public: int lengthOfLIS(vector<int>& nums) { int n = nums.size(), res = 0; if (n < 2) 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], dp[j]+1); } res = max(res, dp[i]); } return res; } };

300. Longest Increasing Subsequence Given an unsorted array of integers, find the length of longest increasing subsequence.

One Pass class NumMatrix { public: NumMatrix(vector<vector<int>>& matrix) { if (matrix.empty() || matrix[0].empty()) return; int m = matrix.size(), n = matrix[0].size(); dp.resize(m+1, vector<int>(n+1, 0)); 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] - dp[i-1][j-1] + matrix[i-1][j-1]; } int sumRegion(int row1, int col1, int row2, int col2) { return dp[row2+1][col2+1] - dp[row1][col2+1] - dp[row2+1][col1] + dp[row1][col1]; } private: vector<vector<int>> dp; };

304. Range Sum Query 2D - Immutable Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper left corner (row1, col1) and lower right corner (row2, col2).

One pass class Solution { public: vector<vector<int>> multiply(vector<vector<int>>& A, vector<vector<int>>& B) { vector<vector<int>> res(A.size(), vector<int>(B[0].size())); for (int i = 0; i < A.size(); ++i){ for (int j = 0; j < A[0].size(); ++j){ if (A[i][j] == 0) continue; for (int k = 0; k < B[0].size(); ++k) if (B[j][k] != 0) res[i][k] += A[i][j] * B[j][k]; } } return res; } };

311. Sparse Matrix Multiplication

DP class Solution { public: vector<int> countSmaller(vector<int>& nums) { int n = nums.size(); vector<int> t; vector<int> res(n, 0); for (int i = n-1; i >= 0; i--){ int left = 0, right = t.size(); while (left < right){ int mid = left + (right - left)/2; if (t[mid] == nums[i]) right = mid; else if (t[mid] < nums[i]) left = mid+1; else right = mid; } res[i] = left; t.insert(t.begin() + right, nums[i]); } return res; } };

315. Count of Smaller Numbers After Self You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i]. Input: nums = [5,2,6,1] Output: [2,1,1,0]

Stack class Solution { public: int longestValidParentheses(string s) { stack<int> stk; int res = 0; int start = 0; for (int i = 0; i < s.size(); i++){ if (s[i] == '('){ stk.push(i); } else{ if (stk.empty()){ start = i+1; } else{ stk.pop(); res = max(res, stk.empty()? i - start + 1: i - stk.top()); } } } return res; } };

32. Longest Valid Parentheses Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.

DP class Solution { public: int coinChange(vector<int>& coins, int amount) { vector<int> dp(amount+1, -1); dp[0] = 0; for (int i = 1; i <= amount; i++){ int temp = INT_MAX; for (auto c : coins){ if (i - c < 0 || dp[i-c] == -1) continue; temp = min(temp, dp[i-c] + 1); } dp[i] = temp < INT_MAX ? temp : -1; } return dp[amount]; } };

322. Coin Change You are given an integer array coins representing coins of different denominations and an integer amount representing a total amount of money. Return the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1. You may assume that you have an infinite number of each kind of coin.

DFS & DP class Solution { public: int longestIncreasingPath(vector<vector<int>>& matrix) { int res = 1, m = matrix.size(), n = matrix[0].size(); vector<vector<int>> dp(m, vector<int>(n, 0)); for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) res = max(res, dfs(matrix, i, j, dp)); return res; } int dfs(vector<vector<int>>& matrix, int i, int j, vector<vector<int>>& dp){ int m = matrix.size(), n = matrix[0].size(); if (dp[i][j]) return dp[i][j]; int res = 1; for (auto d : direction){ int x = i + d[0], y = j + d[1]; if (x < 0 || x >= m || y < 0 || y >= n || matrix[x][y] <= matrix[i][j]) continue; int len = 1 + dfs(matrix, x, y, dp); res = max(res, len); } dp[i][j] = res; return res; } private: vector<vector<int>> direction{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; };

329. Longest Increasing Path in a Matrix Given an m x n integers matrix, return the length of the longest increasing path in matrix. From each cell, you can either move in four directions: left, right, up, or down. You may not move diagonally or move outside the boundary (i.e., wrap-around is not allowed).

Binary Search class Solution { public: int search(vector<int>& nums, int target) { int n = nums.size(); if (n == 0) return -1; int left = 0, right = n-1; while (left <= right){ int mid = left + (right - left)/2; if (nums[mid] == target) return mid; if (nums[mid] >= nums[0]){ if (target < nums[mid] && target >= nums[left]) right = mid-1; else left = mid+1; } else{ if (target > nums[mid] && target <= nums[right]) left = mid+1; else right = mid-1; } } return -1; } };

33. Search in Rotated Sorted Array Input: nums = [4,5,6,7,0,1,2], target = 0 Output: 4

Binary Search class Solution { public: int search(vector<int>& nums, int target) { int n = nums.size(); if (n == 0) return -1; int left = 0, right = n-1; while (left <= right){ int mid = left + (right - left)/2; if (nums[mid] == target) return mid; if (nums[mid] >= nums[0]){ if (target < nums[mid] && target >= nums[left]) right = mid-1; else left = mid+1; } else{ if (target > nums[mid] && target <= nums[right]) left = mid+1; else right = mid-1; } } return -1; } };

33. Search in Rotated Sorted Array There is an integer array nums sorted in ascending order (with distinct values). Prior to being passed to your function, nums is rotated at an unknown pivot index k (0 <= k < nums.length) such that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (0-indexed). For example, [0,1,2,4,5,6,7] might be rotated at pivot index 3 and become [4,5,6,7,0,1,2]. Given the array nums after the rotation and an integer target, return the index of target if it is in nums, or -1 if it is not in nums.

Binary Search class Solution { public: vector<int> searchRange(vector<int>& nums, int target) { int n = nums.size(); vector<int> res = {-1, -1}; if (n == 0 || target < nums[0] || target > nums[n-1]) return res; int left = 0, right = n; while (left < right){ int mid = left + (right - left)/2; if (nums[mid] == target) right = mid; else if (nums[mid] < target) left = mid+1; else right = mid; } if (nums[left] != target) return res; res[0] = left; right = n; while (left < right){ int mid = left + (right - left)/2; if (nums[mid] == target) left = mid + 1; else if (nums[mid] < target) left = mid+1; else right = mid; } res[1] = left-1; return res; } };

34. Find First and Last Position of Element in Sorted Array Given an array of integers nums sorted in ascending order, find the starting and ending position of a given target value. If target is not found in the array, return [-1, -1]. Follow up: Could you write an algorithm with O(log n) runtime complexity?

Deque /** * // This is the interface that allows for creating nested lists. * // You should not implement it, or speculate about its implementation * class NestedInteger { * public: * // Return true if this NestedInteger holds a single integer, rather than a nested list. * bool isInteger() const; * * // Return the single integer that this NestedInteger holds, if it holds a single integer * // The result is undefined if this NestedInteger holds a nested list * int getInteger() const; * * // Return the nested list that this NestedInteger holds, if it holds a nested list * // The result is undefined if this NestedInteger holds a single integer * const vector<NestedInteger> &getList() const; * }; */ class NestedIterator { public: NestedIterator(vector<NestedInteger> &nestedList) { for (auto a : nestedList) q.push_back(a); } int next() { NestedInteger res = q.front(); q.pop_front(); return res.getInteger(); } bool hasNext() { while(q.size()){ NestedInteger p = q.front(); if (p.isInteger()) return true; q.pop_front(); for (int i = 0; i < p.getList().size(); i++) q.insert(q.begin()+i, p.getList()[i]); } return false; } private: deque<NestedInteger> q; };

341. Flatten Nested List Iterator You are given a nested list of integers nestedList. Each element is either an integer or a list whose elements may also be integers or other lists. Implement an iterator to flatten it. Implement the NestedIterator class: NestedIterator(List<NestedInteger> nestedList) Initializes the iterator with the nested list nestedList. int next() Returns the next integer in the nested list. boolean hasNext() Returns true if there are still some integers in the nested list and false otherwise. Input: nestedList = [1,[4,[6]]] Output: [1,4,6]

Stack Hash Heap class Solution { public: vector<int> topKFrequent(vector<int>& nums, int k) { vector<int> res; unordered_map<int, int> hash; priority_queue<pair<int, int>> heap; for (auto num: nums) hash[num]++; for (auto it: hash) heap.push({it.second, it.first}); for (int i = 0; i < k; i++){ res.push_back(heap.top().second); heap.pop(); } return res; } };

347. Top K Frequent Elements Given a non-empty array of integers, return the k most frequent elements.

One Pass class TicTacToe { public: /** Initialize your data structure here. */ TicTacToe(int n) { N = n; rows.resize(n), cols.resize(n); diag = 0, rev_diag = 0; } /** Player {player} makes a move at ({row}, {col}). @param row The row of the board. @param col The column of the board. @param player The player, can be either 1 or 2. @return The current winning condition, can be either: 0: No one wins. 1: Player 1 wins. 2: Player 2 wins. */ int move(int row, int col, int player) { int add = player == 1 ? 1 : -1; rows[row] += add, cols[col] += add; diag += (row == col) ? add : 0; rev_diag += (row + col == N - 1) ? add : 0; return (abs(rows[row]) == N || abs(cols[col]) == N || abs(diag) == N || abs(rev_diag) == N) ? player : 0; } private: vector<int> rows, cols; int diag, rev_diag, N; };

348. Design Tic-Tac-Toe ssume the following rules are for the tic-tac-toe game on an n x n board between two players: A move is guaranteed to be valid and is placed on an empty block. Once a winning condition is reached, no more moves are allowed. A player who succeeds in placing n of their marks in a horizontal, vertical, or diagonal row wins the game. Implement the TicTacToe class: TicTacToe(int n) Initializes the object the size of the board n. int move(int row, int col, int player) Indicates that player with id player plays at the cell (row, col) of the board. The move is guaranteed to be a valid move.

Set class Solution { public: vector<int> intersection(vector<int>& nums1, vector<int>& nums2) { unordered_set<int> s(nums1.begin(), nums1.end()), res; for (auto n : nums2) if (s.find(n) != s.end()) res.insert(n); return vector<int>(res.begin(), res.end()); } };

349. Intersection of Two Arrays Given two arrays, write a function to compute their intersection Input: nums1 = [1,2,2,1], nums2 = [2,2] Output: [2]

Binary Search class Solution { public: int searchInsert(vector<int>& nums, int target) { int n = nums.size(), left = 0, right = n-1; while (left <= right){ int mid = left + (right - left)/2; if (nums[mid] == target) return mid; else if (nums[mid] < target) left = mid + 1; else right = mid - 1; } return left; } };

35. Search Insert Position Given a sorted array of distinct integers and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. Input: nums = [1,3,5,6], target = 5 Output: 2 Input: nums = [1,3,5,6], target = 2 Output: 1

Recursive class Solution { public: string countAndSay(int n) { if (n == 1) return "1"; string word = countAndSay(n-1); int count = 0; string res; for (int i = 0; i < word.size(); i++){ if (i == 0 || word[i] == word[i-1]) count++; else { res += to_string(count) + word[i-1]; count = 1; } } res.push_back(count+'0'); res.push_back(word[word.size()-1]); return res; } };

38. Count and Say The count-and-say sequence is a sequence of digit strings defined by the recursive formula: countAndSay(1) = "1" countAndSay(n) is the way you would "say" the digit string from countAndSay(n-1), which is then converted into a different digit string. To determine how you "say" a digit string, split it into the minimal number of groups so that each group is a contiguous section all of the same character. Then for each group, say the number of characters, then say the character. To convert the saying into a digit string, replace the counts with a number and concatenate every saying. For example, the saying and conversion for digit string "3322251": Given a positive integer n, return the nth term of the count-and-say sequence.

Backtracking class Solution { public: vector<vector<int>> permute(vector<int>& nums) { vector<vector<int>> res; vector<int> path; backtrack(nums, path, res); return res; } void backtrack(vector<int>& nums, vector<int>& path, vector<vector<int>>& res){ if (path.size() == nums.size()){ res.push_back(path); return; } for (auto i : nums){ auto pos = find(path.begin(), path.end(), i); if (pos == path.end()){ path.push_back(i); backtrack(nums, path, res); path.pop_back(); } } } };

46. Permutations

DFS class Solution { public: int numberOfPatterns(int m, int n) { vector<vector<int>> jump(10, vector<int>(10, -1)); vector<bool> visited(10, false); int res = 0; jump[1][3] = jump[3][1] = 2; jump[1][9] = jump[9][1] = 5; jump[1][7] = jump[7][1] = 4; jump[2][8] = jump[8][2] = 5; jump[3][7] = jump[7][3] = 5; jump[3][9] = jump[9][3] = 6; jump[4][6] = jump[6][4] = 5; jump[7][9] = jump[9][7] = 8; for (int i = m; i <= n; i++){ res += dfs(1, i, 1, jump, visited, 0)*4; res += dfs(2, i, 1, jump, visited, 0)*4; res += dfs(5, i, 1, jump, visited, 0); } return res; } int dfs(int curr, int len, int level, vector<vector<int>> &jump, vector<bool> &visited, int res){ if (level == len) return ++res; visited[curr] = true; for (int i = 1; i <= 9; i++){ int middle = jump[curr][i]; if (!visited[i] && (middle == -1 || visited[middle])) res = dfs(i, len, level+1, jump, visited, res); } visited[curr] = false; return res; } };

351. Android Unlock Patterns Android devices have a special lock screen with a 3 x 3 grid of dots. Users can set an "unlock pattern" by connecting the dots in a specific sequence, forming a series of joined line segments where each segment's endpoints are two consecutive dots in the sequence. A sequence of k dots is a valid unlock pattern if both of the following are true: All the dots in the sequence are distinct. If the line segment connecting two consecutive dots in the sequence passes through any other dot, the other dot must have previously appeared in the sequence. No jumps through non-selected dots are allowed. Given two integers m and n, return the number of unique and valid unlock patterns of the Android grid lock screen that consist of at least m keys and at most n keys. Two unlock patterns are considered unique if there is a dot in one sequence that is not in the other, or the order of the dots is different. Input: m = 1, n = 2 Output: 65

Vector class SnakeGame { public: /** Initialize your data structure here. @param width - screen width @param height - screen height @param food - A list of food positions E.g food = [[1,1], [1,0]] means the first food is positioned at [1,1], the second is at [1,0]. */ SnakeGame(int width, int height, vector<vector<int>>& food) { this->width = width; this->height = height; this->food = food; score = 0; snake.push_back({0, 0}); } /** Moves the snake. @param direction - 'U' = Up, 'L' = Left, 'R' = Right, 'D' = Down @return The game's score after the move. Return -1 if game over. Game over when snake crosses the screen boundary or bites its body. */ int move(string direction) { auto head = snake.front(), tail = snake.back(); snake.pop_back(); if (direction == "U") --head[0]; else if (direction == "L") --head[1]; else if (direction == "R") ++head[1]; else if (direction == "D") ++head[0]; if (count(snake.begin(), snake.end(), head) || head[0] < 0 || head[0] >= height || head[1] < 0 || head[1] >= width) return -1; snake.insert(snake.begin(), head); if (!food.empty() && head == food.front()){ food.erase(food.begin()); snake.push_back(tail); ++score; } return score; } private: vector<vector<int>> snake, food; int width, height, score; }; /** * Your SnakeGame object will be instantiated and called as such: * SnakeGame* obj = new SnakeGame(width, height, food); * int param_1 = obj->move(direction); */

353. Design Snake Game Implement the SnakeGame class: SnakeGame(int width, int height, int[][] food) Initializes the object with a screen of size height x width and the positions of the food. int move(String direction) Returns the score of the game after applying one direction move by the snake. If the game is over, return -1.

Hashmap class Logger { public: /** Initialize your data structure here. */ Logger() { } /** Returns true if the message should be printed in the given timestamp, otherwise returns false. If this method returns false, the message will not be printed. The timestamp is in seconds granularity. */ bool shouldPrintMessage(int timestamp, string message) { if (!map.count(message) || (timestamp - map[message]) >= 10){ map[message] = timestamp; return true; } return false; } private: unordered_map<string, int> map; };

359. Logger Rate Limite Design a logger system that receives a stream of messages along with their timestamps. Each unique message should only be printed at most every 10 seconds (i.e. a message printed at timestamp t will prevent other identical messages from being printed until timestamp t + 10). All messages will come in chronological order. Several messages may arrive at the same timestamp.

One Pass class Solution { public: bool isValidSudoku(vector<vector<char>>& board) { for (int i = 0; i < 9; ++i) for (int j = 0; j < 9; ++j){ if (board[i][j] == '.') continue; for (int k = 0; k < 9; ++k){ if (k != j && board[i][k] == board[i][j]) return false; if (k != i && board[k][j] == board[i][j]) return false; } for (int i_ = 3*(i/3); i_ < 3*(i/3+1); ++i_) for (int j_ = 3*(j/3); j_ < 3*(j/3+1); ++j_) if (i_ != i && j_ != j && board[i_][j_] == board[i][j]) return false; } return true; } };

36. Valid Sudoku

DFS class Solution { public: void solveSudoku(vector<vector<char>>& board) { helper(board); } bool helper(vector<vector<char>>& board){ for (int i = 0; i < 9; ++i) for (int j = 0; j < 9; ++j){ if (board[i][j] != '.') continue; for (int k = 1; k <= 9; ++k){ board[i][j] = '0' + k; if (isValid(board, i, j) && helper(board)) return true; board[i][j] = '.'; } return false; } return true; } bool isValid(vector<vector<char>>& board, int x, int y){ for (int i = 0; i < 9; ++i) if (board[i][y] == board[x][y] && i != x) return false; for (int j = 0; j < 9; ++j) if (board[x][j] == board[x][y] && j != y) return false; for (int i = 3 * (x/3); i < 3 * (x/3 + 1); ++i) for (int j = 3 * (y/3); j < 3 * (y/3 + 1); ++j) if (board[i][j] == board[x][y] && i != x && j != y) return false; return true; } };

37. Sudoku Solver

Heap class Solution { public: vector<vector<int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) { vector<vector<int>> res; priority_queue<pair<int, int>, vector<pair<int, int>>, cmp> heap; for (int i = 0; i < min((int)nums1.size(), k); i++){ for (int j = 0; j < min((int)nums2.size(), k); j ++){ if (heap.size() < k) heap.push({nums1[i], nums2[j]}); else if (nums1[i] + nums2[j] < heap.top().first + heap.top().second){ heap.pop(); heap.push({nums1[i], nums2[j]}); } } } while (!heap.empty()){ res.push_back({heap.top().first, heap.top().second}); heap.pop(); } return res; } struct cmp{ bool operator() (pair<int, int> &a, pair<int, int> &b){ return a.first + a.second < b.first + b.second; } }; };

373. Find K Pairs with Smallest Sums You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. Define a pair (u,v) which consists of one element from the first array and one element from the second array. Find the k pairs (u1,v1),(u2,v2) ...(uk,vk) with the smallest sums.

Hashmap class Solution { public: bool canConstruct(string ransomNote, string magazine) { unordered_map<char, int> hash; for (auto c : magazine) hash[c]++; for (auto c : ransomNote){ if (--hash[c] < 0) return false; } return true; } };

383. Ransom Note Given an arbitrary ransom note string and another string containing letters from all the magazines, write a function that will return true if the ransom note can be constructed from the magazines ; otherwise, it will return false. Each letter in the magazine string can only be used once in your ransom note. Input: ransomNote = "aa", magazine = "ab" Output: false Input: ransomNote = "aa", magazine = "aab" Output: true

DFS class Solution { public: vector<vector<int>> combinationSum(vector<int>& candidates, int target) { sort(candidates.begin(), candidates.end()); vector<vector<int>> res; vector<int> path; dfs(candidates, 0, path, res, target); return res; } void dfs(vector<int>& candidates, int start, vector<int>& path, vector<vector<int>>& res, int target){ if (target == 0){ res.push_back(path); return; } for (int i = start; i < candidates.size(); ++i){ if (candidates[i] > target) break; path.push_back(candidates[i]); dfs(candidates, i, path, res, target-candidates[i]); path.pop_back(); } } };

39. Combination Sum Given an array of distinct integers candidates and a target integer target, return a list of all unique combinations of candidates where the chosen numbers sum to target. You may return the combinations in any order. The same number may be chosen from candidates an unlimited number of times. Two combinations are unique if the frequency of at least one of the chosen numbers is different. It is guaranteed that the number of unique combinations that sum up to target is less than 150 combinations for the given input.

Rotate class Solution { public: int maxRotateFunction(vector<int>& A) { int sum = accumulate(A.begin(), A.end(), 0); int n = A.size(), F = 0; for (int i = 0; i < n; ++i) F += i * A[i]; int res = F; for (int i = 1; i < n; ++i){ F += sum - n * A[n-i]; res = max(res, F); } return res; } };

396. Rotate Function Given an array of integers A and let n to be its length. Assume Bk to be an array obtained by rotating the array A k positions clock-wise, we define a "rotation function" F on A as follow: F(k) = 0 * Bk[0] + 1 * Bk[1] + ... + (n-1) * Bk[n-1]. Calculate the maximum value of F(0), F(1), ..., F(n-1).

Divide & Conquer class Solution { public: double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { int m = nums1.size(), n = nums2.size(); int k1 = (m+n+1)/2, k2 = (m+n+2)/2; return 0.5 * (findKth(nums1, nums2, k1, 0, 0) + findKth(nums1, nums2, k2, 0, 0)); } int findKth(vector<int>& nums1, vector<int>& nums2, int k, int i, int j){ int m = nums1.size(), n = nums2.size(); if (i >= m) return nums2[j+k-1]; if (j >= n) return nums1[i+k-1]; if (k == 1) return min(nums1[i], nums2[j]); int mid1 = (i + k/2 - 1) >= m ? INT_MAX : nums1[i + k/2 - 1]; int mid2 = (j + k/2 - 1) >= n ? INT_MAX : nums2[j + k/2 - 1]; if (mid1 < mid2) return findKth(nums1, nums2, k-k/2, i+k/2, j); else return findKth(nums1, nums2, k-k/2, i, j+k/2); } };

4. Median of Two Sorted Arrays Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. Input: nums1 = [1,3], nums2 = [2] Output: 2.00000

DFS class Solution { public: vector<vector<int>> combinationSum2(vector<int>& candidates, int target) { sort(candidates.begin(), candidates.end()); vector<vector<int>> res; vector<int> path; dfs(candidates, 0, path, res, target); return res; } void dfs(vector<int>& candidates, int start, vector<int>& path, vector<vector<int>>& res, int target){ if (target == 0){ res.push_back(path); return; } int previous = -1; for (int i = start; i < candidates.size(); ++i){ if (candidates[i] > target) break; if (candidates[i] == previous) continue; previous = candidates[i]; path.push_back(candidates[i]); dfs(candidates, i+1, path, res, target-candidates[i]); path.pop_back(); } } };

40. Combination Sum II Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sum to target. Each number in candidates may only be used once in the combination. Note: The solution set must not contain duplicate combinations.

DFS class Solution { public: bool canCross(vector<int>& stones) { unordered_map<int, bool> memo; return dfs(stones, 0, 0, memo); } bool dfs(vector<int>& stones, int curr, int jump, unordered_map<int, bool>& memo){ int key = curr | jump << 11; int n = stones.size(); if (memo.count(key)) return memo[key]; if (curr >= n-1) return true; for (int next = curr+1; next < n; next++){ int gap = stones[next] - stones[curr]; if (gap > jump + 1) break; if (gap < jump - 1) continue; if (dfs(stones, next, gap, memo)) { memo[key] = true; return true; } } memo[key] = false; return false; } };

403. Frog Jump A frog is crossing a river. The river is divided into some number of units, and at each unit, there may or may not exist a stone. The frog can jump on a stone, but it must not jump into the water. Given a list of stones' positions (in units) in sorted ascending order, determine if the frog can cross the river by landing on the last stone. Initially, the frog is on the first stone and assumes the first jump must be 1 unit. If the frog's last jump was k units, its next jump must be either k - 1, k, or k + 1 units. The frog can only jump in the forward direction. Input: stones = [0,1,3,5,6,8,12,17] Output: true

Bucket Sort class Solution { public: int firstMissingPositive(vector<int>& nums) { int i = 0; for (int i = 0; i < nums.size(); i++){ while (nums[i] != i+1){ if (nums[i] < 1 || nums[i] > nums.size() || nums[i] == nums[nums[i]-1]) break; swap(nums[i], nums[nums[i]-1]); } } for (int i = 0; i < nums.size(); ++i) if (nums[i] != i+1) return i+1; return nums.size()+1; } };

41. First Missing Positive Given an unsorted integer array nums, find the smallest missing positive integer.

DP class Solution { public: int numberOfArithmeticSlices(vector<int>& A) { int n = A.size(); if (n <= 2) return 0; vector<int> dp(n, 0); for (int i = 2; i < n; i++){ if (A[i] - A[i-1] == A[i-1] - A[i-2]) dp[i] = dp[i-1] + 1; } return accumulate(dp.begin(), dp.end(), 0); } };

413. Arithmetic Slices A sequence of numbers is called arithmetic if it consists of at least three elements and if the difference between any two consecutive elements is the same.

One Pass class Solution { public: string addStrings(string num1, string num2) { int m = num1.size(), n = num2.size(), i = m-1, j = n-1; int carry = 0; string res; while (i >= 0 || j >= 0 || carry){ int sum = ((i >= 0) ? (num1[i--] - '0') : 0) + ((j >= 0) ? (num2[j--] - '0') : 0) + carry; res.insert(res.begin(), (sum%10) + '0'); carry = sum / 10; } return res; } };

415. Add Strings Given two non-negative integers, num1 and num2 represented as string, return the sum of num1 and num2 as a string. Input: num1 = "11", num2 = "123" Output: "134"

DP class Solution { public: bool canPartition(vector<int>& nums) { int sum = accumulate(nums.begin(), nums.end(), 0); if (sum % 2) return false; int target = sum / 2, n = nums.size(); vector<vector<bool>> dp(n+1, vector<bool>(target+1, false)); for (int i = 0; i <= n; ++i){ dp[i][0] = true; } for (int i = 1; i <= n; ++i){ for (int j = nums[i-1]; j <= target; ++j) dp[i][j] = dp[i-1][j] || dp[i-1][j-nums[i-1]]; } return dp[n][target]; } };

416. Partition Equal Subset Sum Given a non-empty array nums containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.

DFS class Solution { public: vector<vector<int>> direction = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; vector<vector<int>> pacificAtlantic(vector<vector<int>>& matrix) { if (matrix.size() == 0 || matrix[0].size() == 0) return {}; vector<vector<int>> res; int m = matrix.size(), n = matrix[0].size(); vector<vector<bool>> pacific(m, vector<bool>(n, false)); vector<vector<bool>> atlantic(m, vector<bool>(n, false)); for (int i = 0; i < m; i++){ dfs(matrix, pacific, INT_MIN, i, 0); dfs(matrix, atlantic, INT_MIN, i, n-1); } for (int j = 0; j < n; j++){ dfs(matrix, pacific, INT_MIN, 0, j); dfs(matrix, atlantic, INT_MIN, m-1, j); } for (int i = 0; i < m; i++){ for (int j = 0; j < n; j++){ if (pacific[i][j] && atlantic[i][j]) res.push_back(vector<int>{i, j}); } } return res; } void dfs(vector<vector<int>>& matrix, vector<vector<bool>>& visited, int prev, int i, int j){ int m = matrix.size(), n = matrix[0].size(); if (i < 0 || i >= m || j < 0 || j >= n || visited[i][j] || matrix[i][j] < prev) return; visited[i][j] = true; for (auto dir : direction) dfs(matrix, visited, matrix[i][j], i + dir[0], j + dir[1]); } };

417. Pacific Atlantic Water Flow Given an m x n matrix of non-negative integers representing the height of each unit cell in a continent, the "Pacific ocean" touches the left and top edges of the matrix and the "Atlantic ocean" touches the right and bottom edges. Water can only flow in four directions (up, down, left, or right) from a cell to another one with height equal or lower. Find the list of grid coordinates where water can flow to both the Pacific and Atlantic ocean.

Monotonic Decreasing Stack class Solution { public: int trap(vector<int>& height) { int res = 0; stack<int> s; for (int i = 0; i < height.size();){ if (s.empty() || height[s.top()] >= height[i]) s.push(i++); else{ int lowest = s.top(); s.pop(); if (!s.empty()) { int l = s.top(); int w = i - l - 1; int h = min(height[l], height[i]) - height[lowest]; res += w * h; } } } return res; } };

42. Trapping Rain Water

Recursive class Solution { public: int pathSum(TreeNode* root, int sum) { if (root == nullptr) return 0; return dfs(root, sum) + pathSum(root->left, sum) + pathSum(root->right, sum); } int dfs(TreeNode* root, int sum) { int res = 0; if (root == nullptr) return res; if (root->val == sum) res++; res += dfs(root->left, sum - root->val); res += dfs(root->right, sum - root->val); return res; } };

437. Path Sum III You are given a binary tree in which each node contains an integer value. Find the number of paths that sum to a given value. The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes). The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.

Two Pointers class Solution { public: int compress(vector<char>& chars) { int n = chars.size(), curr = 0; for (int i = 0, j = 0; i < n; i = j){ while (j < n && chars[i] == chars[j]) ++j; chars[curr++] = chars[i]; if (j - i == 1) continue; for (auto c : to_string(j-i)) chars[curr++] = c; } return curr; } };

443. String Compression Given an array of characters chars, compress it using the following algorithm: Begin with an empty string s. For each group of consecutive repeating characters in chars: If the group's length is 1, append the character to s. Otherwise, append the character followed by the group's length. T he compressed string s should not be returned separately, but instead be stored in the input character array chars. Note that group lengths that are 10 or longer will be split into multiple characters in chars. After you are done modifying the input array, return the new length of the array. Input: chars = ["a","a","b","b","c","c","c"] Output: Return 6, and the first 6 characters of the input array should be: ["a","2","b","2","c","3"]

BFS class Solution { public: int jump(vector<int>& nums) { int n = nums.size(), curr_max = 0, next_max = 0, i = 0; for (int level = 0; level < n; ++level){ if (curr_max >= n-1) return level; for (; i <= curr_max; ++i) next_max = max(next_max, i+nums[i]); curr_max = next_max; } return 0; } }; class Solution { public: int jump(vector<int>& nums) { int n = nums.size(); if (n <= 1) return 0; vector<int> dp(n, INT_MAX-1); dp[0] = 0; for (int i = 0; i < n; i++){ if (i+nums[i] >= n-1) return dp[i]+1; for (int j = 1; j <= nums[i]; j++){ dp[i+j] = min(dp[i+j], dp[i]+1); } } return dp[n]; } }; Greedy class Solution { public: int jump(vector<int>& nums) { int n = nums.size(); int i = 0, curr_e = 0, next_e = 0, res = 0; while (curr_e < n-1){ for (; i <= curr_e; ++i) next_e = max(next_e, i + nums[i]); if (curr_e == next_e) return -1; curr_e = next_e; res++; } return res; } };

45. Jump Game II Given an array of non-negative integers nums, you are initially positioned at the first index of the array. Each element in the array represents your maximum jump length at that position. Your goal is to reach the last index in the minimum number of jumps. You can assume that you can always reach the last index.

Hashmap class Solution { public: string frequencySort(string s) { unordered_map<char, int> map; priority_queue<pair<int, char>> max_heap; string res; for (auto c : s) map[c]++; for (auto m : map) max_heap.push(make_pair(m.second, m.first)); while (!max_heap.empty()){ auto m = max_heap.top(); max_heap.pop(); for (int i = 0; i < m.first; i++) res += m.second; } return res; } };

451. Sort Characters By Frequency Given a string s, sort it in decreasing order based on the frequency of characters, and return the sorted string. Input: s = "tree" Output: "eert"

Hashmap class Solution { public: int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) { int res = 0, n = A.size(); unordered_map<int, int> hash1, hash2; for (int i = 0; i < n; i++){ for (int j = 0; j < n; j++){ hash1[A[i] + B[j]]++; hash2[C[i] + D[j]]++; } } for (auto m : hash1) res += m.second * hash2[-m.first]; return res; } };

454. 4Sum II Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) there are such that A[i] + B[j] + C[k] + D[l] is zero. To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. All integers are in the range of -228 to 228 - 1 and the result is guaranteed to be at most 231 - 1. Input: A = [ 1, 2] B = [-2,-1] C = [-1, 2] D = [ 0, 2] Output: 2

Backtracking class Solution { public: vector<vector<int>> permute(vector<int>& nums) { vector<vector<int>> res; vector<int> curr; vector<bool> visited(nums.size(), false); backtrack(nums, 0, curr, res, visited); return res; } void backtrack(vector<int>& nums, int level, vector<int>& curr, vector<vector<int>>& res, vector<bool> visited){ if (level == nums.size()){ res.push_back(curr); return; } for (int i = 0; i < nums.size(); i++){ if (visited[i]) continue; visited[i] = true; curr.push_back(nums[i]); backtrack(nums, level+1, curr, res, visited); visited[i] = false; curr.pop_back(); } } };

46. Permutations Given a collection of distinct integers, return all possible permutations.

Backtracking class Solution { public: vector<vector<int>> permuteUnique(vector<int>& nums) { sort(nums.begin(), nums.end()); vector<vector<int>> res; vector<int> curr; vector<bool> visited(nums.size(), false); backtrack(nums, curr, res, visited); return res; } void backtrack(vector<int>& nums, vector<int>& curr, vector<vector<int>>& res, vector<bool> visited){ if (curr.size() == nums.size()){ res.push_back(curr); return; } for (int i = 0; i < nums.size(); i++){ if (visited[i]) continue; if (i > 0 && nums[i] == nums[i - 1] && visited[i - 1] == 0) continue; visited[i] = true; curr.push_back(nums[i]); backtrack(nums, curr, res, visited); visited[i] = false; curr.pop_back(); } } };

47. Permutations II

Hashmap class Solution { public: vector<vector<string>> groupAnagrams(vector<string>& strs) { unordered_map<string, int> map; vector<vector<string>> res; for (int i = 0; i < strs.size(); ++i){ string temp = strs[i]; sort(temp.begin(), temp.end()); if (!map.count(temp)){ map[temp] = res.size(); res.push_back({}); } res[map[temp]].push_back(strs[i]); } return res; } };

49. Group Anagrams Given an array of strings strs, group the anagrams together. You can return the answer in any order. An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

D&C class Solution { public: double myPow(double x, int n) { if (x == 1 || n == 0) return 1.0; if (n < 0) return 1.0/power(x, (-(n+1))) / x; return power(x, n); } double power(double x, int n){ if (n == 0) return 1; double res = power(x, n/2); if (n%2 == 0) return res * res; return res*res*x; } };

50. Pow(x, n)

Hashmap class Solution { public: vector<string> findWords(vector<string>& words) { unordered_set<char> set1{'q','w','e','r','t','y','u','i','o','p'}; unordered_set<char> set2{'a','s','d','f','g','h','j','k','l'}; unordered_set<char> set3{'z','x','c','v','b','n','m'}; vector<string> res; for (auto word : words){ int r1 = 0, r2 = 0, r3 = 0; for (auto c : word){ if (c < 'a') c += 32; if (set1.count(c)) r1 = 1; if (set2.count(c)) r2 = 1; if (set3.count(c)) r3 = 1; if (r1 + r2 + r3 != 1) break; } if (r1 + r2 + r3 == 1) res.push_back(word); } return res; } };

500. Keyboard Row Given a List of words, return the words that can be typed using letters of alphabet on only one row's of American keyboard like the image below.

Heap class Solution { public: vector<string> findRelativeRanks(vector<int>& nums) { vector<string> res(nums.size(), ""); priority_queue<pair<int, int>> heap; for (int i = 0; i < nums.size(); i++) heap.push({nums[i], i}); for (int i = 0; i < nums.size(); i++){ int index = heap.top().second; heap.pop(); if (i == 0) res[index] = "Gold Medal"; else if (i == 1) res[index] = "Silver Medal"; else if (i == 2) res[index] = "Bronze Medal"; else res[index] = to_string(i+1); } return res; } };

506. Relative Ranks Given scores of N athletes, find their relative ranks and the people with the top three highest scores, who will be awarded medals: "Gold Medal", "Silver Medal" and "Bronze Medal".

Backtracking class Solution { public: vector<vector<string>> solveNQueens(int n) { vector<vector<string>> res; vector<string> queens(n, string(n, '.')); backtrack(n, 0, queens, res); return res; } void backtrack(int n, int i, vector<string>& queens, vector<vector<string>>& res){ if (i == n){ res.push_back(queens); return; } for (int j = 0; j < n; j++){ if (!isValid(queens, i, j)) continue; queens[i][j] = 'Q'; backtrack(n, i+1, queens, res); queens[i][j] = '.'; } } bool isValid(vector<string>& queens, int row, int col){ for (int i = 0; i < row; i++){ if (queens[i][col] == 'Q') return false; } for (int i = row-1, j = col-1; i >= 0 && j >= 0; i--, j--){ if (queens[i][j] == 'Q') return false; } for (int i = row-1, j = col+1; i >= 0 && j < queens.size(); i--, j++){ if (queens[i][j] == 'Q') return false; } return true; } };

51. N-Queens

DFS class Solution { public: vector<vector<string>> solveNQueens(int n) { vector<vector<string>> res; vector<int> path(n, -1); dfs(0, path, res); return res; } void dfs(int row, vector<int>& path, vector<vector<string>>& res){ int n = path.size(); if (row == n){ vector<string> temp; for (int i = 0; i < n; ++i){ string s(n, '.'); s[path[i]] = 'Q'; temp.push_back(s); } res.push_back(temp); return; } for (int i = 0; i < n; ++i){ if (!isValid(path, row, i)) continue; path[row] = i; dfs(row+1, path, res); path[row] = -1; } } bool isValid(vector<int>& path, int row, int col){ for (int i = 0; i < row; ++i){ if (path[i] == col) return false; if (abs(i-row) == abs(path[i]-col)) return false; } return true; } };

51. N-Queens

Queue class Solution { public: int findBottomLeftValue(TreeNode* root) { vector<int> res; if (root == nullptr) return 0; queue<TreeNode*> que; que.push(root); while (que.size()){ res.push_back(que.front()->val); int len = que.size(); for (int i = 0; i < len; i++){ TreeNode *node = que.front(); que.pop(); if (node->left) que.push(node->left); if (node->right) que.push(node->right); } } return res.back(); } };

513. Find Bottom Left Tree Value Given a binary tree, find the leftmost value in the last row of the tree.

Queue class Solution { public: vector<int> largestValues(TreeNode* root) { vector<int> res; if (root == nullptr) return res; queue<TreeNode*> que; que.push(root); while (que.size()){ int len = que.size(); int temp = INT_MIN; for (int i = 0; i < len; i++){ TreeNode *node = que.front(); que.pop(); temp = max(temp, node->val); if (node->left) que.push(node->left); if (node->right) que.push(node->right); } res.push_back(temp); } return res; } };

515. Find Largest Value in Each Tree Row Given the root of a binary tree, return an array of the largest value in each row of the tree (0-indexed).

Hashmap class Solution { public: int findMaxLength(vector<int>& nums) { unordered_map<int, int> hash{{0, -1}}; int res = 0, sum = 0; for (int i = 0; i < nums.size(); i++){ sum += (nums[i] == 0) ? -1 : 1; if (hash.count(sum)) res = max(res, i - hash[sum]); else hash[sum] = i; } return res; } };

525. Contiguous Array Given a binary array, find the maximum length of a contiguous subarray with equal number of 0 and 1.

Binary Search class Solution { public: Solution(vector<int>& w) { sum = w; n = w.size(); for (int i = 1; i < n; ++i) sum[i] = sum[i-1] + w[i]; } int pickIndex() { int temp = rand() % sum.back(); int left = 0, right = n-1; while (left < right){ int mid = left + (right - left) / 2; if (sum[mid] <= temp) left = mid + 1; else right = mid; } return right; } private: vector<int> sum; int n; };

528. Random Pick with Weight You are given an array of positive integers w where w[i] describes the weight of ith index (0-indexed). We need to call the function pickIndex() which randomly returns an integer in the range [0, w.length - 1]. pickIndex() should return the integer proportional to its weight in the w array. For example, for w = [1, 3], the probability of picking the index 0 is 1 / (1 + 3) = 0.25 (i.e 25%) while the probability of picking the index 1 is 3 / (1 + 3) = 0.75 (i.e 75%). More formally, the probability of picking index i is w[i] / sum(w).

One Pass class Solution { public: vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click) { if (board.empty() || board[0].empty()) return {}; int m = board.size(), n = board[0].size(), row = click[0], col = click[1], cnt = 0; if (board[row][col] == 'M') { board[row][col] = 'X'; } else { for (int i = -1; i < 2; ++i) { for (int j = -1; j < 2; ++j) { int x = row + i, y = col + j; if (x < 0 || x >= m || y < 0 || y >= n) continue; if (board[x][y] == 'M') ++cnt; } } if (cnt > 0) { board[row][col] = cnt + '0'; } else { board[row][col] = 'B'; for (int i = -1; i < 2; ++i) { for (int j = -1; j < 2; ++j) { int x = row + i, y = col + j; if (x < 0 || x >= m || y < 0 || y >= n) continue; if (board[x][y] == 'E') { vector<int> nextPos{x, y}; updateBoard(board, nextPos); } } } } } return board; } };

529. Minesweeper

DP class Solution { public: int maxSubArray(vector<int>& nums) { int n = nums.size(); int dp[n]; dp[0] = nums[0]; int res = INT_MIN; for (int i = 1; i < n; i++) dp[i] = dp[i-1] >=0 ? dp[i-1] + nums[i] : nums[i]; for (int i = 0; i < n; i++) res = max(res, dp[i]); return res; } };

53. Maximum Subarray Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

One Pass class Solution { public: vector<int> spiralOrder(vector<vector<int>>& matrix) { int m = matrix.size(), n = matrix[0].size(); int left = 0, right = n-1, top = 0, down = m-1; vector<int> res; while (true){ for (int i = left; i <= right; i++) res.push_back(matrix[top][i]); if (++top > down) break; for (int j = top; j <= down; j++) res.push_back(matrix[j][right]); if (--right < left) break; for (int i = right; i >= left; i--) res.push_back(matrix[down][i]); if (--down < top) break; for (int j = down; j >= top; j--) res.push_back(matrix[j][left]); if (++left > right) break; } return res; } };

54. Spiral Matrix Given an m x n matrix, return all elements of the matrix in spiral order

One Pass class Solution { public: string reverseStr(string s, int k) { for (int i = 0; i < s.size(); i+=2*k){ if (i+k <= s.size()) reverse(i+s.begin(), i+s.begin()+k); else reverse(i+s.begin(), s.end()); } return s; } };

541. Reverse String II Given a string s and an integer k, reverse the first k characters for every 2k characters counting from the start of the string. If there are fewer than k characters left, reverse all of them. If there are less than 2k but greater than or equal to k characters, then reverse the first k characters and left the other as original.

DP class Solution { public: vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) { int m = matrix.size(), n = matrix[0].size(); vector<vector<int>> dp(m, vector<int>(n, INT_MAX-1)); for (int i = 0; i < m; i++){ for (int j = 0; j < n; j++){ if (matrix[i][j] == 0) dp[i][j] = 0; else{ if (i > 0) dp[i][j] = min(dp[i][j], dp[i-1][j] + 1); if (j > 0) dp[i][j] = min(dp[i][j], dp[i][j-1] + 1); } } } for (int i = m-1; i >= 0; i--){ for (int j = n-1; j >= 0; j--){ if (matrix[i][j] != 0){ if (i < m-1) dp[i][j] = min(dp[i][j], dp[i+1][j] + 1); if (j < n-1) dp[i][j] = min(dp[i][j], dp[i][j+1] + 1); } } } return dp; } };

542. 01 Matrix Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell. The distance between two adjacent cells is 1. Input: [[0,0,0], [0,1,0], [1,1,1]] Output: [[0,0,0], [0,1,0], [1,2,1]]

Recursive class Solution { public: int diameterOfBinaryTree(TreeNode* root) { if (root == nullptr) return 0; int leftDepth = maxDepth(root->left); int rightDepth = maxDepth(root->right); return max(leftDepth + rightDepth, max(diameterOfBinaryTree(root->left), diameterOfBinaryTree(root->right))); } int maxDepth(TreeNode* root){ if (root == nullptr) return 0; if (root->left == nullptr && root->right == nullptr) return 1; int leftDepth = maxDepth(root->left); int rightDepth = maxDepth(root->right); return max(leftDepth, rightDepth) + 1; } };

543. Diameter of Binary Tree Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a binary tree is the length of the longest path between any two nodes in a tree. This path may or may not pass through the root.

DFS class Solution { public: int findCircleNum(vector<vector<int>>& M) { int res = 0, n = M.size(); vector<bool> visited(n, false); for (int i = 0; i < n; i++){ if (visited[i]) continue; dfs(M, i, visited); res++; } return res; } void dfs(vector<vector<int>>& M, int k, vector<bool>& visited){ visited[k] = true; for (int i = 0; i < M.size(); i++){ if (!M[i][k] || visited[i]) continue; dfs(M, i, visited); } } };

547. Friend Circles There are N students in a class. Some of them are friends, while some are not. Their friendship is transitive in nature. For example, if A is a direct friend of B, and B is a direct friend of C, then A is an indirect friend of C. And we defined a friend circle is a group of students who are direct or indirect friends. Given a N*N matrix M representing the friend relationship between students in the class. If M[i][j] = 1, then the ith and jth students are direct friends with each other, otherwise not. And you have to output the total number of friend circles among all the students.

DP class Solution { public: bool canJump(vector<int>& nums) { int n = nums.size(); if (n == 1) return true; if (nums[0] == 0) return false; vector<bool> dp(n, false); dp[0] = true; for (int i = 1; i < n; ++i){ for (int j = i-1; j >= 0;--j){ if (nums[j] >= (i-j) && dp[j]){ dp[i] = true; break; }; } } return dp[n-1]; } }; Greedy class Solution { public: bool canJump(vector<int>& nums) { int max_pos = 0, n = nums.size(); for (int i = 0; i < n; i++){ max_pos = max(max_pos, nums[i]+i); if (max_pos >= n-1) return true; if (max_pos == i) return false; } return false; } };

55. Jump Game Given an array of non-negative integers nums, you are initially positioned at the first index of the array. Each element in the array represents your maximum jump length at that position. Determine if you are able to reach the last index.

Hashmap class Solution { public: int leastBricks(vector<vector<int>>& wall) { int res = 0; unordered_map<int, int> hash; for (auto row : wall){ int sum = 0; for (int i = 0; i < row.size()-1; i++){ sum += row[i]; res = max(res, ++hash[sum]); } } return wall.size() - res; } };

554. Brick Wall There is a brick wall in front of you. The wall is rectangular and has several rows of bricks. The bricks have the same height but different width. You want to draw a vertical line from the top to the bottom and cross the least bricks. The brick wall is represented by a list of rows. Each row is a list of integers representing the width of each brick in this row from left to right. If your line go through the edge of a brick, then the brick is not considered as crossed. You need to find out how to draw the line to cross the least bricks and return the number of crossed bricks. You cannot draw a line just along one of the two vertical edges of the wall, in which case the line will obviously cross no bricks. Input: [[1,2,2,1], [3,1,2], [1,3,2], [2,4], [3,1,2], [1,3,1,1]] Output: 2

One Pass class Solution { public: vector<vector<int>> merge(vector<vector<int>>& intervals) { if (intervals.size() < 2) return intervals; vector<vector<int>> res; sort(intervals.begin(), intervals.end()); int start = intervals[0][0], end = intervals[0][1]; for (int i = 1; i < intervals.size(); i++){ if (intervals[i][0] > end){ res.push_back({start, end}); start = intervals[i][0]; end = intervals[i][1]; } else{ end = max(end, intervals[i][1]); } } res.push_back({start, end}); return res; } };

56. Merge Intervals Given an array of intervals where intervals[i] = [starti, endi], merge all overlapping intervals, and return an array of the non-overlapping intervals that cover all the intervals in the input.

Hashmap class Solution { public: int subarraySum(vector<int>& nums, int k) { int sum = 0, res = 0; unordered_map<int, int> hash{{0, 1}}; for (int i = 0; i < nums.size(); i++){ sum += nums[i]; res += hash[sum-k]; hash[sum]++; } return res; } };

560. Subarray Sum Equals K Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k.

Recursive class Solution { public: bool isSubtree(TreeNode* s, TreeNode* t) { if (s == nullptr) return false; if (isSameTree(s, t)) return true; return isSubtree(s->left, t) || isSubtree(s->right, t); } bool isSameTree(TreeNode* s, TreeNode* t){ if (s == nullptr && t == nullptr) return true; if (s == nullptr || t == nullptr) return false; if (s->val != t->val) return false; return isSameTree(s->left, t->left) && isSameTree(s->right, t->right); } };

572. Subtree of Another Tree Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and node values with a subtree of s. A subtree of s is a tree consists of a node in s and all of this node's descendants. The tree s could also be considered as a subtree of itself.

Hashmap class Solution { public: bool validSquare(vector<int>& p1, vector<int>& p2, vector<int>& p3, vector<int>& p4) { unordered_set<int> set{getDistance(p1, p2), getDistance(p1, p3), getDistance(p1, p4), getDistance(p2, p3), getDistance(p2, p4), getDistance(p3, p4)}; return set.count(0) == 0 && set.size() == 2; } int getDistance(vector<int>& p1, vector<int>&p2){ return (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]); } };

593. Valid Square Given the coordinates of four points in 2D space, return whether the four points could construct a square. The coordinate (x,y) of a point is represented by an integer array with two integers

Cycle class Solution { public: ListNode* rotateRight(ListNode* head, int k) { if(head == nullptr) return head; ListNode *newhead = head, *tail = head; int len = 1; while(tail->next){ len++; tail = tail->next; } tail->next = head; if(k %= len){ for(int i = 0; i < len - k; i++){ tail = tail->next; } } newhead = tail->next; tail->next = nullptr; return newhead; } };

61. Rotate List Given a linked list, rotate the list to the right by k places, where k is non-negative. Input: 1->2->3->4->5->NULL, k = 2 Output: 4->5->1->2->3->NULL Explanation: rotate 1 steps to the right: 5->1->2->3->4->NULL rotate 2 steps to the right: 4->5->1->2->3->NULL

DP class Solution { public: int uniquePaths(int m, int n) { vector<vector<int>> dp(m, vector<int>(n, 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]; } };

62. Unique Paths A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). How many possible unique paths are there?

DP class Solution { public: int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) { int m = obstacleGrid.size(); int n = obstacleGrid[0].size(); vector<vector<int>> dp(m, vector<int>(n, 0)); for (int i = 0; i < m; ++i){ if (obstacleGrid[i][0] == 1) break; dp[i][0] = 1; } for (int j = 0; j < n; ++j){ if (obstacleGrid[0][j] == 1) break; dp[0][j] = 1; } for (int i = 1; i < m; ++i){ for (int j = 1; j < n; ++j){ if (obstacleGrid[i][j] == 1) continue; dp[i][j] = dp[i][j-1] + dp[i-1][j]; } } return dp[m-1][n-1]; } };

63. Unique Paths II A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). Now consider if some obstacles are added to the grids. How many unique paths would there be? An obstacle and space is marked as 1 and 0 respectively in the grid.

DP class Solution { public: int minPathSum(vector<vector<int>>& grid) { int m = grid.size(), n = grid[0].size(); vector<vector<int>> dp(m, vector<int>(n, 0)); dp[0][0] = grid[0][0]; for (int i = 1; i < m; ++i) dp[i][0] = dp[i-1][0] + grid[i][0]; for (int j = 1; j < n; ++j) dp[0][j] = dp[0][j-1] + grid[0][j]; for (int i = 1; i < m; ++i){ for (int j = 1; j < n; ++j){ dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]; } } return dp[m-1][n-1]; } };

64. Minimum Path Sum Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.

DP class Solution { public: int countSubstrings(string s) { int n = s.size(); int res = 0; vector<vector<bool>> dp(n, vector<bool>(n, false)); for (int i = n-1; i >= 0; i--){ for (int j = i; j < n; j++){ dp[i][j] = s[i] == s[j] && (j - i <= 2 || dp[i+1][j-1]); if (dp[i][j]) ++res; } } return res; } };

647. Palindromic Substrings Given a string, your task is to count how many palindromic substrings in this string. The substrings with different start indexes or end indexes are counted as different substrings even they consist of same characters. Input: "aaa" Output: 6 Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa".

One Pass class Solution { public: vector<string> fullJustify(vector<string>& words, int maxWidth) { int len = 0, n = words.size(); vector<string> res; vector<string> curr; for (int i = 0; i <= n; i++){ if (i == n || len + words[i].size() > maxWidth){ int space = maxWidth - len + 1; int m = curr.size(); curr[m-1] = curr[m-1].substr(0, curr[m-1].size()-1); for (int j = 0; j < space; ++j){ if (i != n && m != 1) curr[j%(m-1)] += ' '; else curr[m-1] += ' '; } string temp; for (auto c : curr) temp += c; res.push_back(temp); len = 0; curr.resize(0); } if (i == n) break; curr.push_back(words[i] + ' '); len += words[i].size() + 1; } return res; } };

68. Text Justification Input: words = ["This", "is", "an", "example", "of", "text", "justification."], maxWidth = 16 Output: [ "This is an", "example of text", "justification. " ]

Binary Search class Solution { public: int mySqrt(int x) { if (x <= 1) return x; int left = 0, right = x; while (left < right){ int mid = left + (right - left)/2; if (mid <= x/mid) left = mid+1; else right = mid; } return right-1; } }; 第一类: 需查找和目标值完全相等的数 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[mid] < target) left = mid + 1; else right = mid - 1; } return -1; 第二类: 查找第一个不小于目标值的数,可变形为查找最后一个小于目标值的数 int left = 0, right = nums.size(); while (left < right) { int mid = left + (right - left) / 2; if (nums[mid] < target) left = mid + 1; else right = mid; } return right; 第三类: 查找第一个大于目标值的数,可变形为查找最后一个不大于目标值的数 int left = 0, right = nums.size(); while (left < right) { int mid = left + (right - left) / 2; if (nums[mid] <= target) left = mid + 1; else right = mid; } return right;

69. Sqrt(x)

Hashmap & PQ class Solution { public: vector<string> topKFrequent(vector<string>& words, int k) { unordered_map<string, int> hashmap; priority_queue<pair<string, int>, vector<pair<string, int>>, cmp> q; vector<string> res; for (auto w : words) ++hashmap[w]; for (auto h : hashmap){ q.push(make_pair(h.first, h.second)); if (q.size() > k) q.pop(); } for (int i = q.size()-1; i >= 0; i--){ res.insert(res.begin(), q.top().first); q.pop(); } return res; } struct cmp{ bool operator()(pair<string, int>& a, pair<string, int>& b){ return a.second > b.second || (a.second == b.second && a.first < b.first); } }; };

692. Top K Frequent Words Given a non-empty list of words, return the k most frequent elements. Your answer should be sorted by frequency from highest to lowest. If two words have the same frequency, then the word with the lower alphabetical order comes first.

DFS class Solution { public: int maxAreaOfIsland(vector<vector<int>>& grid) { m = grid.size(); n = grid[0].size(); int res = 0; for (int i = 0; i < m; ++i) for (int j = 0; j < n; ++j) if (grid[i][j] == 1) res = max(res, dfs(grid, i, j)); return res; } int dfs(vector<vector<int>>& grid, int i, int j){ if (i < 0 || i >= m || j < 0 || j >= n || grid[i][j] == 0) return 0; grid[i][j] = 0; int res = 1; for (auto d : direction){ res += dfs(grid, i + d[0], j + d[1]); } return res; } private: int m; int n; vector<vector<int>> direction{{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; };

695. Max Area of Island

DFS class Solution { public: vector<vector<int>> direction{{-1, 0}, {1, 0}, {0, 1}, {0, -1}}; int maxAreaOfIsland(vector<vector<int>>& grid) { if (grid.size() == 0 || grid[0].size() == 0) return 0; int res = 0; for (int i = 0; i < grid.size(); i++){ for (int j = 0; j < grid[0].size(); j++){ if (grid[i][j] == 1) res = max(res, dfs(grid, i, j)); } } return res; } int dfs(vector<vector<int>>& grid, int i, int j){ if (grid[i][j] == 0) return 0; grid[i][j] = 0; int area = 1; for (auto dir : direction){ int x = i + dir[0]; int y = j + dir[1]; if (x >= 0 && x < grid.size() && y >= 0 && y < grid[0].size()) area += dfs(grid, x, y); } return area; } };

695. Max Area of Island Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) connected 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water. Find the maximum area of an island in the given 2D array. (If there is no island, the maximum area is 0.)

Hashmap class Solution { public: int reverse(int x) { int res = 0; while (x != 0){ if (abs(res) > INT_MAX / 10) return 0; res = 10*res + x%10; x = x/10; } return res; } };

7. Reverse Integer Given a signed 32-bit integer x, return x with its digits reversed. If reversing x causes the value to go outside the signed 32-bit integer range [-231, 231 - 1], then return 0. Input: x = 123 Output: 321

Array class MyHashMap { public: /** Initialize your data structure here. */ MyHashMap() { map.resize(1000, vector<int>()); } /** value will always be non-negative. */ void put(int key, int value) { int hashkey = key/1000; if (map[hashkey].empty()) map[hashkey].resize(1000, -1); map[hashkey][key%1000] = value; } /** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */ int get(int key) { int hashkey = key/1000; if (!map[hashkey].empty()) return map[hashkey][key%1000]; return -1; } /** Removes the mapping of the specified value key if this map contains a mapping for the key */ void remove(int key) { int hashkey = key/1000; if (!map[hashkey].empty()) map[hashkey][key%1000] = -1; } private: vector<vector<int>> map; }; /** * Your MyHashMap object will be instantiated and called as such: * MyHashMap* obj = new MyHashMap(); * obj->put(key,value); * int param_2 = obj->get(key); * obj-

706. Design HashMap Design a HashMap without using any built-in hash table libraries. To be specific, your design should include these functions: put(key, value) : Insert a (key, value) pair into the HashMap. If the value already exists in the HashMap, update the value. get(key): Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key. remove(key) : Remove the mapping for the value key if this map contains the mapping for the key.

DFS class Solution { public: vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) { if (image[sr][sc] != newColor) helper(image, sr, sc, image[sr][sc], newColor); return image; } void helper(vector<vector<int>>& image, int i, int j, int oldColor, int newColor){ if (i >= image.size() || j >= image[0].size() || image[i][j] != oldColor) return; vector<vector<int>> dir{{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; image[i][j] = newColor; for (auto d : dir) helper(image, i+d[0], j+d[1], oldColor, newColor); return; } };

733. Flood Fill An image is represented by a 2-D array of integers, each integer representing the pixel value of the image (from 0 to 65535). Given a coordinate (sr, sc) representing the starting pixel (row and column) of the flood fill, and a pixel value newColor, "flood fill" the image.

Two Pointers class Solution { public: void sortColors(vector<int>& nums) { int red_i = 0; int blue_i = nums.size()-1; for (int i = 0; i < blue_i + 1;){ if (nums[i] == 0) swap(nums[i++], nums[red_i++]); else if (nums[i] == 1) i++; else if (nums[i] == 2) swap(nums[i], nums[blue_i--]); } } };

75. Sort Colors Given an array nums with n objects colored red, white, or blue, sort them in-place so that objects of the same color are adjacent, with the colors in the order red, white, and blue. We will use the integers 0, 1, and 2 to represent the color red, white, and blue, respectively.

Sliding Window class Solution { public: string minWindow(string s, string t) { string res = ""; int left = 0, count = 0, minWindow = INT_MAX; unordered_map<char, int> hash; unordered_set<char> set(t.begin(), t.end()); for (auto c : t) ++hash[c]; for (int right = 0; right < s.size(); ++right){ if (!set.count(s[right])) continue; if (hash[s[right]]-- > 0) ++count; while (count == t.size()){ if (right - left + 1 < minWindow){ minWindow = right - left + 1; res = s.substr(left, minWindow); } if (set.count(s[left]) && ++hash[s[left]] > 0) --count; ++left; } } return res; } };

76. Minimum Window Substring Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).

Heap class Solution { public: string reorganizeString(string S) { unordered_map<char, int> hashmap; priority_queue<pair<int, char>> max_heap; for (auto c : S) ++hashmap[c]; for (auto h : hashmap){ if (h.second > (S.size()+1)/2) return ""; max_heap.push(make_pair(h.second, h.first)); } string res; while (max_heap.size() >= 2){ auto a = max_heap.top(); max_heap.pop(); auto b = max_heap.top(); max_heap.pop(); res += a.second; res += b.second; if (--a.first > 0) max_heap.push(a); if (--b.first > 0) max_heap.push(b); } if (max_heap.size()) res += max_heap.top().second; return res; } };

767. Reorganize String Given a string S, check if the letters can be rearranged so that two characters that are adjacent to each other are not the same. If possible, output any possible result. If not possible, return the empty string. Input: S = "aab" Output: "aba

Backtracking class Solution { public: vector<vector<int>> combine(int n, int k) { vector<vector<int>> res; vector<int> path; backtrack(n, k, 1, 0, path, res); return res; } void backtrack(int n, int k, int start, int curr, vector<int>& path, vector<vector<int>>& res){ if (curr == k){ res.push_back(path); return; } for (int i = start; i <= n; ++i){ path.push_back(i); backtrack(n, k, i+1, curr+1, path, res); path.pop_back(); } } };

77. Combinations

Backtracking class Solution { public: vector<vector<int>> combine(int n, int k) { vector<vector<int>> res; vector<int> curr; backtrack(n, k, 1, curr, res); return res; } void backtrack(int n, int k, int level, vector<int>& curr, vector<vector<int>>& res){ if (curr.size() == k){ res.push_back(curr); return; } for (int i = level; i <= n; i++){ curr.push_back(i); backtrack(n, k, i+1, curr, res); curr.pop_back(); } } };

77. Combinations Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. You may return the answer in any order.

Backtracking class Solution { public: vector<vector<int>> subsets(vector<int>& nums) { int n = nums.size(); vector<int> path; vector<vector<int>> res; backtrack(nums, 0, path, res); return res; } void backtrack(vector<int>& nums, int curr, vector<int> &path, vector<vector<int>> &res){ res.push_back(path); for (int i = curr; i < nums.size(); i++){ path.push_back(nums[i]); backtrack(nums, i+1, path, res); path.pop_back(); } } };

78. Subsets

DFS class Solution { public: bool exist(vector<vector<char>>& board, string word) { if (word.empty()) return false; m = board.size(); n = board[0].size(); vector<vector<bool>> visited(m, vector<bool>(n, false)); for (int i = 0; i < m; ++i) for (int j = 0; j < n; ++j){ if (board[i][j] != word[0]) continue; if (dfs(board, i, j, visited, word.substr(1, word.size()-1))) return true; } return false; } private: int m; int n; vector<vector<int>> direction{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; bool dfs(vector<vector<char>>& board, int i, int j, vector<vector<bool>> visited, string word){ if (word.size() == 0) return true; visited[i][j] = true; for (auto d : direction){ if (i+d[0] < 0 || i+d[0] >= m || j+d[1] < 0 || j+d[1] >= n || board[i+d[0]][j+d[1]] != word[0] || visited[i+d[0]][j+d[1]]) continue; if (dfs(board, i+d[0], j+d[1], visited, word.substr(1, word.size()-1))) return true; } visited[i][j] = false; return false; } };

79. Word Search

Backtracking class Solution { public: vector<vector<int>> direction{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; bool exist(vector<vector<char>>& board, string word) { int m = board.size(), n = board[0].size(); vector<vector<bool>> visited(m, vector<bool>(n, false)); for (int i = 0; i < m; i++){ for (int j = 0; j < n; j++){ if (backtrack(board, word, i, j, 0, visited)) return true; } } return false; } bool backtrack(vector<vector<char>>& board, string word, int i, int j , int curr, vector<vector<bool>>& visited){ if (curr == word.size()) return true; int m = board.size(), n = board[0].size(); if (i < 0 || i >= m || j < 0 || j >= n || visited[i][j] || board[i][j] != word[curr]) return false; visited[i][j] = true; for (auto dir : direction){ if (backtrack(board, word, i + dir[0], j + dir[1], curr + 1, visited)){ visited[i][j] = false; return true; } } visited[i][j] = false; return false; } };

79. Word Search Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cells, where "adjacent" cells are horizontally or vertically neighboring. The same letter cell may not be used more than once. Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED" Output: true

DFS class Solution { public: bool exist(vector<vector<char>>& board, string word) { if (word.empty()) return false; m = board.size(); n = board[0].size(); vector<vector<bool>> visited(m, vector<bool>(n, false)); for (int i = 0; i < m; ++i) for (int j = 0; j < n; ++j){ if (board[i][j] != word[0]) continue; if (dfs(board, i, j, visited, word.substr(1, word.size()-1))) return true; } return false; } private: int m; int n; vector<vector<int>> direction{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; bool dfs(vector<vector<char>>& board, int i, int j, vector<vector<bool>> visited, string word){ if (word.size() == 0) return true; visited[i][j] = true; for (auto d : direction){ if (i+d[0] < 0 || i+d[0] >= m || j+d[1] < 0 || j+d[1] >= n || board[i+d[0]][j+d[1]] != word[0] || visited[i+d[0]][j+d[1]]) continue; if (dfs(board, i+d[0], j+d[1], visited, word.substr(1, word.size()-1))) return true; } visited[i][j] = false; return false; } };

79. Word Search Given an m x n board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cells, where "adjacent" cells are horizontally or vertically neighboring. The same letter cell may not be used more than once.

One Pass class Solution { public: int myAtoi(string s) { int res{0}, sign{1}, i{0}; int n = s.size(); while (i < n && s[i] == ' ') i++; if (i < n && (s[i] == '+' || s[i] == '-')){ sign = (s[i++] == '+') ? 1 : -1; } while (i < n && s[i] >= '0' && s[i] <= '9'){ if (res > INT_MAX / 10 || (res == INT_MAX / 10 && s[i] - '0' > 7)) { return (sign == 1) ? INT_MAX : INT_MIN; } res = 10 * res + (s[i++] - '0'); } return res * sign; } };

8. String to Integer (atoi) Implement the myAtoi(string s) function, which converts a string to a 32-bit signed integer (similar to C/C++'s atoi function). The algorithm for myAtoi(string s) is as follows: Read in and ignore any leading whitespace. Check if the next character (if not already at the end of the string) is '-' or '+'. Read this character in if it is either. This determines if the final result is negative or positive respectively. Assume the result is positive if neither is present. Read in next the characters until the next non-digit charcter or the end of the input is reached. The rest of the string is ignored. Convert these digits into an integer (i.e. "123" -> 123, "0032" -> 32). If no digits were read, then the integer is 0. Change the sign as necessary (from step 2). If the integer is out of the 32-bit signed integer range [-231, 231 - 1], then clamp the integer so that it remains in the range. Specifically, integers less than -231 should be clamped to -231, and integers greater than 231 - 1 should be clamped to 231 - 1. Return the integer as the final result.

Fast&Slow Pointers class Solution { public: int removeDuplicates(vector<int>& nums) { if (nums.size() <= 2) return nums.size(); int slow = 2, fast = 2; while (fast < nums.size()){ if (nums[fast] != nums[slow-2]) nums[slow++] = nums[fast]; fast++; } return slow; } };

80. Remove Duplicates from Sorted Array II Given a sorted array nums, remove the duplicates in-place such that duplicates appeared at most twice and return the new length. Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory. Example 1: Given nums = [1,1,1,2,2,3], Your function should return length = 5, with the first five elements of nums being 1, 1, 2, 2 and 3 respectively. It doesn't matter what you leave beyond the returned length.

DFS class Solution { public: bool splitArraySameAverage(vector<int>& A) { sort(A.begin(), A.end()); n = A.size(); sum = accumulate(A.begin(), A.end(), 0); return dfs(A, 0, 1, 0); } private: int sum; int n; bool dfs(vector<int>& A, int start, int count, int curr_sum){ if (count > n/2) return false; for (int i = start; i < n; i++){ curr_sum += A[i]; if (curr_sum * (n - count) == (sum - curr_sum) * count) return true; if (curr_sum * (n - count) > (sum - curr_sum) * count) break; if (dfs(A, i+1, count+1, curr_sum)) return true; curr_sum -= A[i]; } return false; } }; DP class Solution { public: bool splitArraySameAverage(vector<int>& nums) { bool possible = false; int sum = accumulate(nums.begin(), nums.end(), 0); int n = nums.size(); for (int k = 1; k <= n/2 && !possible; k++) if ((k*sum)%n == 0) possible = true; if (!possible) return false; vector<unordered_set<int>> dp(n/2+1); dp[0].insert(0); for (auto num : nums) for (int i = n/2; i >= 1; i--) for (auto a : dp[i-1]) dp[i].insert(a+num); for (int k = 1; k <= n/2; k++) if ((k*sum)%n == 0 && dp[k].count(k*sum/n)) return true; return false; } };

805. Split Array With Same Average In a given integer array A, we must move every element of A to either list B or list C. (B and C initially start empty.) Return true if and only if after such a move, it is possible that the average value of B is equal to the average value of C, and B and C are both non-empty.

Linked List class Solution { public: ListNode* deleteDuplicates(ListNode* head) { if (head == nullptr || head->next == nullptr) return head; ListNode *curr = head->next, *prev = head; while (curr){ if (prev->val == curr->val) prev->next = curr->next; else prev = curr; curr = curr->next; } return head; } };

83. Remove Duplicates from Sorted List Given a sorted linked list, delete all duplicates such that each element appear only once.

Recursive class Solution { public: vector<int> sumOfDistancesInTree(int N, vector<vector<int>>& edges) { vector<int> res(N), count(N); tree.resize(N, vector<int>{}); for (auto e : edges){ tree[e[0]].push_back(e[1]); tree[e[1]].push_back(e[0]); } post_order(res, count, 0, -1); pre_order(res, count, 0, -1); return res; } void post_order(vector<int>& res, vector<int>& count, int curr, int prev){ for (int i : tree[curr]){ if (i == prev) continue; post_order(res, count, i, curr); count[curr] += count[i]; res[curr] += res[i] + count[i]; } count[curr]++; } void pre_order(vector<int>& res, vector<int>& count, int curr, int prev){ for (int i : tree[curr]){ if (i == prev) continue; res[i] = res[curr] - count[i] + count.size() - count[i]; pre_order(res, count, i, curr); } } private: vector<vector<int>> tree; };

834. Sum of Distances in Tree An undirected, connected tree with N nodes labelled 0...N-1 and N-1 edges are given. The ith edge connects nodes edges[i][0] and edges[i][1] together. Return a list ans, where ans[i] is the sum of the distances between node i and all other nodes. Input: N = 6, edges = [[0,1],[0,2],[2,3],[2,4],[2,5]] Output: [8,12,6,10,10,10]

Monotonic Increasing Stack class Solution { public: int largestRectangleArea(vector<int>& heights) { stack<int> s; heights.push_back(0); int res = 0; for (int i = 0; i < heights.size();){ if (s.empty() || heights[s.top()] < heights[i]) s.push(i++); else{ int top = s.top(); s.pop(); res = max(res, heights[top] * (s.empty() ? i : i - s.top() - 1)); } } return res; } };

84. Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.

DP class Solution { public: int maximalRectangle(vector<vector<char>>& matrix) { if (matrix.empty()) return 0; int m = matrix.size(), n = matrix[0].size(), res = 0; vector<vector<int>> width(m, vector<int>(n, 0)); for (int i = 0; i < m; i++) if (matrix[i][0] == '1') width[i][0] = 1; for (int i = 0; i < m; i++) for (int j = 1; j < n; j++) if (matrix[i][j] == '1') width[i][j] = width[i][j-1]+1; for (int i = 0; i < m; i++) for (int j = 0; j < n; j++){ int w = INT_MAX; for (int k = i; k>=0; k--){ if (width[k][j] == 0) break; w = min(w, width[k][j]); if (w>0) res = max(res, w*(i-k+1)); } } return res; } };

85. Maximal Rectangle Given a rows x cols binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.

Linked List class Solution { public: ListNode* partition(ListNode* head, int x) { ListNode *small = new ListNode(-1), *p1 = small; ListNode *large = new ListNode(-1), *p2 = large; while (head){ if (head->val < x){ p1->next = head; p1 = p1->next; } else{ p2->next = head; p2 = p2->next; } head = head->next; } p1->next = large->next; p2->next = nullptr; return small->next; } };

86. Partition List Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x. You should preserve the original relative order of the nodes in each of the two partitions.

DP class Solution { public: bool isScramble(string s1, string s2) { if (s1.size() != s2.size()) return false; int N = s1.size(); bool dp[N+1][N][N]; fill_n(&dp[0][0][0], (N+1)*N*N, false); for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) dp[1][i][j] = s1[i] == s2[j]; for (int n = 1; n <= N; n++) for (int i = 0; i+n <= N; i++) for (int j = 0; j+n <= N; j++){ for (int k = 1; k < n; k++){ if ((dp[k][i][j] && dp[n-k][i+k][j+k]) || (dp[k][i][j+n-k] && dp[n-k][i+k][j])){ dp[n][i][j] = true; break; } } } return dp[N][0][0]; } };

87. Scramble String We can scramble a string s to get a string t using the following algorithm: If the length of the string is 1, stop. If the length of the string is > 1, do the following: Split the string into two non-empty substrings at a random index, i.e., if the string is s, divide it to x and y where s = x + y. Randomly decide to swap the two substrings or to keep them in the same order. i.e., after this step, s may become s = x + y or s = y + x. Apply step 1 recursively on each of the two substrings x and y. Given two strings s1 and s2 of the same length, return true if s2 is a scrambled string of s1, otherwise, return false.

Two Pointers class Solution { public: void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) { int i = m-1, j = n-1, curr = m+n-1; while (i >= 0 || j >= 0){ if (i < 0 || (j >= 0 && nums2[j] >= nums1[i])) nums1[curr--] = nums2[j--]; else if (j < 0 || nums2[j] < nums1[i]) nums1[curr--] = nums1[i--]; } } };

88. Merge Sorted Array Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Note: The number of elements initialized in nums1 and nums2 are m and n respectively. You may assume that nums1 has enough space (size that is equal to m + n) to hold additional elements from nums2. Example: Input: nums1 = [1,2,3,0,0,0], m = 3 nums2 = [2,5,6], n = 3 Output: [1,2,2,3,5,6]

Two Pointer class Solution { public: bool isPalindrome(int x) { if (x < 0) return false; int div = 1; while (x/div >= 10) div *= 10; while (x > 0){ int left = x/div; int right = x%10; if (left != right) return false; x = (x%div)/10; div /= 100; } return true; } };

9. Palindrome Number Given an integer x, return true if x is palindrome integer. An integer is a palindrome when it reads the same backward as forward. For example, 121 is palindrome while 123 is not. Input: x = 121 Output: true

Backtracking class Solution { public: vector<vector<int>> subsetsWithDup(vector<int>& nums) { sort(nums.begin(), nums.end()); vector<vector<int>> res; vector<int> path; backtrack(nums, path, 0, res); return res; } void backtrack(vector<int>& nums, vector<int>& path, int step, vector<vector<int>>& res){ res.push_back(path); for (int i = step; i < nums.size(); ++i){ path.push_back(nums[i]); backtrack(nums, path, i+1, res); path.pop_back(); while (i + 1 < nums.size() && nums[i+1] == nums[i]) ++i; } } };

90. Subsets II Given an integer array nums that may contain duplicates, return all possible subsets (the power set). The solution set must not contain duplicate subsets. Return the solution in any order.

DP class Solution { public: int numDecodings(string s) { vector<int> dp(s.size()+1, 0); dp[0] = 1; dp[1] = (s[0] == '0') ? 0 : 1; for (int i = 2; i <= s.size(); ++i){ dp[i] = (s[i-1] == '0') ? 0 : dp[i-1]; if ((s[i-2] == '1') || (s[i-2] == '2' && s[i-1] <= '6')) dp[i] += dp[i-2]; } return dp.back(); } };

91. Decode Ways A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' -> 1 'B' -> 2 ... 'Z' -> 26 Given a non-empty string containing only digits, determine the total number of ways to decode it. The answer is guaranteed to fit in a 32-bit integer. Input: s = "12" Output: 2 Explanation: It could be decoded as "AB" (1 2) or "L" (12).

DFS class Solution { public: vector<string> restoreIpAddresses(string s) { vector<string> res; vector<string> path; dfs(s, 0, path, res); return res; } void dfs(string s, int start, vector<string>& path, vector<string>& res){ if (path.size() == 4 && start == s.size()){ string temp; for (auto s : path) temp += s + '.'; res.push_back(temp.substr(0, temp.size()-1)); return; } if (path.size() == 4 || start == s.size()) return; for (int i = start; i < start+3 && i < s.size(); i++){ int num = stoi(s.substr(start, i-start+1)); if (num > 255) continue; path.push_back(s.substr(start, i-start+1)); dfs(s, i+1, path, res); path.pop_back(); if (num == 0) break; } } };

93. Restore IP Addresses Given a string s containing only digits, return all possible valid IP addresses that can be obtained from s. You can return them in any order. A valid IP address consists of exactly four integers, each integer is between 0 and 255, separated by single dots and cannot have leading zeros. For example, "0.1.2.201" and "192.168.1.1" are valid IP addresses and "0.011.255.245", "192.168.1.312" and "[email protected]" are invalid IP addresses.

DFS&BFS class Solution { public: vector<vector<int>> direction = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; int shortestBridge(vector<vector<int>>& A) { int res = 0, n = A.size(), x = -1, y = -1; for (int i = 0; i < n; ++i){ for (int j = 0; j < n; ++j){ if (A[i][j] == 0) continue; x = i; y = j; break; } if (x != -1) break; } if (x == -1) return res; queue<pair<int, int>> q; dfs(A, x, y, q); while (!q.empty()){ int m = q.size(); for (int i = 0; i < m; ++i){ x = q.front().first; y = q.front().second; q.pop(); for (auto dir : direction){ int new_x = x + dir[0], new_y = y + dir[1]; if (new_x < 0 || new_x >= n || new_y < 0 || new_y >= n || A[new_x][new_y] == 2) continue; if (A[new_x][new_y] == 1) return res; A[new_x][new_y] = 2; q.push({new_x, new_y}); } } ++res; } return res; } void dfs(vector<vector<int>>& A, int x, int y, queue<pair<int, int>>& q){ int n = A.size(); if (x < 0 || x >= n || y < 0 || y >= n || A[x][y] == 0 || A[x][y] == 2) return; A[x][y] = 2; q.push({x, y}); for (auto dir : direction) dfs(A, x+dir[0], y+dir[1], q); } };

934. Shortest Bridge In a given 2D binary array A, there are two islands. (An island is a 4-directionally connected group of 1s not connected to any other 1s.) Now, we may change 0s to 1s so as to connect the two islands together to form 1 island. Return the smallest number of 0s that must be flipped. (It is guaranteed that the answer is at least 1.)

Stack /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: vector<int> inorderTraversal(TreeNode* root) { vector<int> res; stack<TreeNode*> s; TreeNode* p = root; while (!s.empty() || p){ if (p){ s.push(p); p = p->left; } else{ p = s.top(); s.pop(); res.push_back(p->val); p = p->right; } } return res; } };

94. Binary Tree Inorder Traversal

Stack class Solution { public: vector<int> inorderTraversal(TreeNode* root) { vector<int> res; stack<TreeNode*> stk; TreeNode* curr = root; while (stk.size() || curr){ if (curr){ stk.push(curr); curr = curr->left; } else{ curr = stk.top(); stk.pop(); res.push_back(curr->val); curr = curr->right; } } return res; } };

94. Binary Tree Inorder Traversal

Recursion /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: vector<TreeNode*> generateTrees(int n) { return helper(1, n); } vector<TreeNode*> helper(int start, int end){ vector<TreeNode*> subTree; if (start > end){ subTree.push_back(nullptr); return subTree; } for (int i = start; i <= end; ++i){ vector<TreeNode*> left = helper(start, i-1); vector<TreeNode*> right = helper(i+1, end); for (auto l : left){ for (auto r : right){ TreeNode *root = new TreeNode(i); root->left = l; root->right = r; subTree.push_back(root); } } } return subTree; } };

95. Unique Binary Search Trees II Given an integer n, return all the structurally unique BST's (binary search trees), which has exactly n nodes of unique values from 1 to n. Return the answer in any order.

Dynamic Programming class Solution { public: int numTrees(int n) { vector<int> dp(n+1); dp[0] = 1; dp[1] = 1; for (int i = 2; i<=n; i++){ for (int j = 0; j < i; j++){ dp[i] += dp[j]*dp[i-j-1]; } } return dp[n]; } };

96. Unique Binary Search Trees Given n, how many structurally unique BST's (binary search trees) that store values 1 ... n?

DP class Solution { public: bool isInterleave(string s1, string s2, string s3) { int m = s1.size(), n = s2.size(); if (m+n != s3.size()) return false; vector<vector<bool>> dp(m+1, vector<bool>(n+1, false)); dp[0][0] = true; for (int i = 1; i <= m; i++){ if (s1[i-1] == s3[i-1]) dp[i][0] = true; else break; } for (int j = 1; j <= n; j++){ if (s2[j-1] == s3[j-1]) dp[0][j] = true; else break; } for (int i = 1; i <= m; i++) for (int j = 1; j <= n; j++){ dp[i][j] = (dp[i-1][j] && (s1[i-1] == s3[i+j-1])) || (dp[i][j-1] && (s2[j-1] == s3[i+j-1])); } return dp[m][n]; } };

97. Interleaving String Given strings s1, s2, and s3, find whether s3 is formed by an interleaving of s1 and s2.

Recursion /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: bool isValidBST(TreeNode* root) { return helper(root, INT_MIN, INT_MAX); } bool helper(TreeNode* root, int lower, int upper){ if (root == nullptr) return true; return root->val > lower && root->val < upper && helper(root->left, lower, root->val) && helper(root->right, root->val, upper); } };

98. Validate Binary Search Tree

Stack class Solution { public: bool isValidBST(TreeNode* root) { if (root == nullptr) return true; stack<TreeNode*> stk; TreeNode *curr = root, *pre = nullptr; while (curr || stk.size()){ if (curr){ stk.push(curr); curr = curr->left; } else{ curr = stk.top(); stk.pop(); if (pre != nullptr && pre->val >= curr->val) return false; pre = curr; curr = curr->right; } } return true; } };

98. Validate Binary Search Tree

Tree Map class TimeMap { public: /** Initialize your data structure here. */ TimeMap() {} void set(string key, string value, int timestamp) { m[key].insert({timestamp, value}); } string get(string key, int timestamp) { auto it = m[key].upper_bound(timestamp); if (it == m[key].begin()) return ""; return prev(it)->second; } private: unordered_map<string, map<int, string>> m; };

981. Time Based Key-Value Store Create a timebased key-value store class TimeMap, that supports two operations. 1. set(string key, string value, int timestamp) Stores the key and value, along with the given timestamp. 2. get(string key, int timestamp) Returns a value such that set(key, value, timestamp_prev) was called previously, with timestamp_prev <= timestamp. If there are multiple such values, it returns the one with the largest timestamp_prev. If there are no values, it returns the empty string ("").

One Pass class Solution { public: vector<vector<int>> intervalIntersection(vector<vector<int>>& firstList, vector<vector<int>>& secondList) { vector<vector<int>> res; int i = 0, j = 0; while (i < firstList.size() && j < secondList.size()){ if ((firstList[i][0] >= secondList[j][0] && firstList[i][0] <= secondList[j][1]) || (secondList[j][0] >= firstList[i][0] && secondList[j][0] <= firstList[i][1])){ int start = max(firstList[i][0], secondList[j][0]); int end = min(firstList[i][1], secondList[j][1]); res.push_back({start, end}); } if (firstList[i][1] < secondList[j][1]) i++; else j++; } return res; } };

986. Interval List Intersections You are given two lists of closed intervals, firstList and secondList, where firstList[i] = [starti, endi] and secondList[j] = [startj, endj]. Each list of intervals is pairwise disjoint and in sorted order. Return the intersection of these two interval lists.

Stack /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: void recoverTree(TreeNode* root) { pair<TreeNode*, TreeNode*> broken; stack<TreeNode*> s; TreeNode* p = root; TreeNode* prev = nullptr; while (!s.empty() || p){ if (p) { s.push(p); p = p->left; } else{ p = s.top(); s.pop(); detect(broken, prev, p); prev = p; p = p->right; } } swap(broken.first->val, broken.second->val); } void detect(pair<TreeNode*, TreeNode*>& broken, TreeNode* prev, TreeNode* p){ if (prev == nullptr || prev->val <= p->val) return; if (broken.first == nullptr) broken.first = prev; broken.second = p; } };

99. Recover Binary Search Tree You are given the root of a binary search tree (BST), where exactly two nodes of the tree were swapped by mistake. Recover the tree without changing its structure. Follow up: A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?


Set pelajaran terkait

2.5-2.7 Functions & Their Graphs Study Set

View Set

International Management Quizzes

View Set

Chapter 20 Delegation and Supervison

View Set