Recording my coding practice routine 🚀
leetcode: Math
-
- Two Pointers Solution: watch out for the int overflow
- HashSet
- a natural number is a sum of two squares if and only if each prime factor that's 3 modulo 4 occurs to an even power in the number's prime factorization. link
-
537. Complex Number Multiplication
- String manipulation
-
- Newton Method
- Binary Search
-
-
prune out cases
int countPrimes(int n) { if (n<3) return 0; vector<int> isPrime(n+1, 1); int count = 1; for (int i=3; i<n; i+=2){ if (isPrime[i]==1) { count++; for (int j = i; j<=n/i; j+=2) isPrime[j*i] = 0; } } return count; }
-
- 462. Minimum Moves to Equal Array Elements II
- Choose the median: rigorous proof
- Replace sort: use quickSelect finding kth largest element.
- 670. Maximum Swap
- One pass from tail to head
- 343. Integer Break ⭐
- 368. Largest Divisible Subset
- Dynamic Programming
- From least to most, iteratively solve by map
leetcode: math
-
- XOR'ing a number by itself results in 0
- XOR is commutative and associative
-
1073. Adding Two Negabinary Numbers⭐
-
Interesting!
-
Change from add from binary numbers
C++:
vector<int> addBinary(vector<int>& A, vector<int>& B) { vector<int> res; int carry = 0, i = A.size() - 1, j = B.size() - 1; while (i >= 0 || j >= 0 || carry) { if (i >= 0) carry += A[i--]; if (j >= 0) carry += B[j--]; res.push_back(carry & 1); carry = (carry >> 1); } reverse(res.begin(), res.end()); return res; } vector<int> addNegabinary(vector<int>& A, vector<int>& B) { vector<int> res; int carry = 0, i = A.size() - 1, j = B.size() - 1; while (i >= 0 || j >= 0 || carry) { if (i >= 0) carry += A[i--]; if (j >= 0) carry += B[j--]; res.push_back(carry & 1); carry = -(carry >> 1); } while (res.size() > 1 && res.back() == 0) res.pop_back(); reverse(res.begin(), res.end()); return res; }
-
leetcode: Binary Search
-
- Don't treat it as a 2D matrix, just treat it as a sorted list
-
981. Time Based Key-Value Store
- This is new. We need to write a class first.
- Hash map + map: lower_bound
- Use binary search ⭐
-
-
Watch out for processing
n<0
double myPow(double x, int n) { if (n==0) return 1; if (n<0) return 1/x * myPow(1/x, -(n+1)); return (n%2) ? myPow(x*x, n/2)*x:myPow(x*x, n/2); }
-
Bit manipulation
-
leetcode: Binary Search
-
4. Median of Two Sorted Arrays⭐
- Binary Search: median number index property
- Search in the short array
- edge cases solved by adding imaginary nodes (smart)
- Binary Search: median number index property
-
-
Easy binary search problem
if (nums[mid] >= target) hi = mid; else lo = mid + 1;
-
-
34. Find First and Last Position of Element in Sorted Array
- Binary search for the left and right boundary (2 pass) ⭐ (a trick to make mid bias to the right)
- Another way to search right bound: search left bound for
target + 1
-
744. Find Smallest Letter Greater Than Target
- Find right bound
-
153. Find Minimum in Rotated Sorted Array
-
Remember:
int findMin(vector<int>& nums) { int lo = 0, hi = nums.size() - 1, mid; while (lo < hi) { mid = (lo + hi) >> 1; if (nums[mid] > nums[hi]) lo = mid + 1; // compare with right one else hi = mid; } return nums[lo]; }
-
Another way
int findMin(vector<int> &num) { int start=0,end=num.size()-1; while (start<end) { if (num[start]<num[end]) return num[start]; int mid = (start+end)/2; if (num[mid]>=num[start]) { start = mid+1; } else { end = mid; } } return num[start]; }
-
-
- find the peak only on its right elements( cut the array to half)
- Tricky one: because search we can always get a solution by searching the local maximum side
leetcode: array
Binary Search
-
- Typical Solution
- Difference of
l < r
andl <= r
- first should be right open interval
- second should be right closed interval
-
33. Search in Rotated Sorted Array ⭐
- Find the smallest one
- Perform normal binary search
-
81. Search in Rotated Sorted Array II
- Handle special condition where
nums[left] == nums[mid]
- Handle special condition where
leetcode: array
- 1. Two Sum
- Hash Map: record indexes:star:
- Sorted two-sum search problem (more complex)
- 15. 3Sum ⭐
- Classic
- Sort + Decompose to two sum problem
- 16. 3Sum Closest
- Similar to 15
- Add conditional codes for a few specific cases (faster).
- 923. 3Sum With Multiplicity
- Hash map
leetcode: backtracking
- 77. Combinations
- iterative
- recursive
- backtrack
- 78. Subsets
- recursive
- iterative
- bit manipulation
leetcode: array
- 18. 4Sum
- attention on how to eliminate repeated one
- fast 2-pointer to solve 2-sum, and recursion to reduce the N-sum to 2-sum
- 169. Majority Element
- this solution collection
- Hash Table
- Sort
- Moore Voting Algorithm:star:
- Bit Manipulation
leetcode: array
- 55. Jump Game:
- Record maximum reach of jump
- 11. Container With Most Water
- Two pointer: how to traverse all possible feasible solutions? (Pruning)
leetcode: daily challenge
- 283. Move Zeroes
- scan once, move non-zero to the front
leetcode: graph
- 133. Clone Graph
- learn to write BFS/DFS to traverse a graph
- In this problem, avoid copying the same node for multiple times (mapping from an original node to its copy)
- 207. Course Schedule
- topological sort to detect circle, we first transform it to the adjacency-list representation.
- 289. Game of Life ⭐
- Simulation problem
- In place solution: use 2nd-bit as change number (genius)
leetcode: daily challenge
-
- O(n) solution use XOR
-
- Floyd Cycle detection algorithm
- Use set to detect cycle
leetcode: Linked List
-
- Linked List add two number
-
-
Construct on merge two sorted list
-
Merge two adjacent lists every iteration
I agree with @cqnkxy. During 1st iteration, we merge two lists(every list is N) into one, this will make K down to K / 2. During 2nd iteration, we merge two lists(every list is 2N) into one, this will make K / 2 down to k /4. During 3rd iteration, we merge two lists(every list is 4N) into one, this will make K / 4 down to k /8. And so forth... I think when we merge two lists, the complexity is O(list1.length) + O(list2.length). So the total complexity is: (2N) * (K / 2) + (4N) * (K / 4) + (8N) * (K / 8) + .............. + (2^logK*N) * (K / (2 ^logK)) = logK*KN
-
Priority-queue or Heap
-
priority_queue<Type, Container, Functional>
default Functional is <
struct compare { bool operator()(const ListNode* l, const ListNode* r) { return l->val > r->val; // output minimum one } };
-
Heap in C++: Maximum Heap
static bool heapComp(ListNode* a, ListNode* b) { return a->val > b->val; }
-
Heap in C++ STL | make_heap(), push_heap(), pop_heap(), sort_heap(), is_heap, is_heap_until()
-
-
-
-
use set or list to record appearance
unordered_set<int> setG (G.begin(), G.end()); ... setG.count(head->val) ... // appearance ... setG.erase(...) ... // delete
-
-
- If no reverse: stack:star:
leetcode: Linked List
-
- Find the tail and reconnect
- Use the circle list
-
-
Reverse Node classical code block (use frequently)
# Not using dummy node prev, cur, nxt = None, head, head while cur: nxt = cur.next cur.next = prev prev = cur cur = nxt return prev
-
recursive solution
-
leetcode: Linked List
-
-
iterative solution: base solution
cur->next = (l1) ? l1:l2;
-
recursive solution
-
-
- Two pointer approach: simple and intuitive
- my own solution: first submission (complicated thought)
-
109. Convert Sorted List to Binary Search Tree
- Recursion:
- two pointer approach for finding out the middle element of a linked list ⭐
- Recursion + Conversion to Array ⭐
- Inorder Simulation
- Recursion:
-
- classical swap problem: use dummy node
-
- logic == 206 + 92
-
standard code block
ListNode *tmp = pre->next; pre->next = cur->next; cur->next = cur->next->next; pre->next->next = tmp;
leetcode: Dynamic Programming
- 332 Coin Change
- Dynamic Programming
- DFS search (pruning out unnecessary situations): much faster ⭐
- 413 Arithmetic Slices
- 221 Maximal Square ⭐
- brute force search (my solution)
- Dynamic Programming
- 64 Minimum Path Sum ⭐
- 85 Maximal Rectangle ⭐
- similar to 221 (but solution is totally different)
- similar to 84: histogram square
- 85 Maximal Rectangle ⭐
- Search left and right
- use stack ⭐
- 70 Climbing Stairs
Fibonacci array
- 53 Maximum Subarray ⭐
- classical subarray sum problem: O(n) time, O(1) space
- 121 Best Time to Buy and Sell Stock ⭐
- transform to 53 problem
- intuitive solution: record minimum price
leetcode: Dynamic Programming
- 198 House Robber:
- O(1) space implementation
- 213 House Robber II:
- Two way House Robber
- 132 Palindrome Partition:
- Record isPalindrome and partition number
- prune cases: expand out from current letter
- 62 Unique Path:
- O(n) space implementation
- 63 Unique Path II:
- Similar implementation: watch out for the corner case
leetcode: tree
- 99 Binary Tree Right Side View:
Depth-first Search
Breadth-First Search
- postorder search and only record first one of the level
- 111 Minimum Depth of Binary Tree:
Depth-first Search
Breadth-First Search
- 112 Path Sum:
Depth-first Search
Breadth-First Search
- 103 Binary Tree Zigzag Level Order Traversal:
Depth-first Search
Breadth-First Search
- use deque
- 94 Binary Tree Inorder Traversal
- 113 Path Sum II:
Depth-first Search
Breadth-First Search
leetcode: tree
-
96 Unique Binary Search Trees:
Dynamic Programing
-
95 Unique Binary Search Trees II:
Dynamic Programing
-
106 Construct Binary Tree from Inorder and Postorder Traversal ⭐
- Solved in recursion version. This one is a quite classic problem.
-
100 Same Tree:
Inorder Traversal
-
99 Recover Binary Search Tree ⭐
- First, could be solved by a inorder traversal (only two nodes are swapped)
- Second, a very interesting way to solve by
Morris Traversal
. Look at this website and this discussion.
leetcode: linked list
- 206 Reverse Linked List
- Iterative: dummy node
- recursive: straight-forward
- 92 Reverse Linked List II
- iterative: dummy node