Leetcode 75
Leetcode 75
Valid anagram: Use array of 75, (int)s[i] - 48, O(n), O(75). Or use unordered_map
for universal unicode, check for 0, O(n), O(n) values.
firstNonRepeatingCharacter: "abcab" -> 'c', "abcabc" -> '_'. Solution: Use hash to
store key: char, value: freq, position to avoid O(2N) looping, but O(3N) data
structure. Or: Use array[26]. 'a'- 98 = 0.
Group Anagram:
-> Solution 1: O(N*K*26): key is "98979797979710097....97" represent "aggg"
value is the string itself
-> Solution 2: O(N*K*log(K)): counting sort. Sort words then keep track of
similar group
Array:
Contains Duplicate: Just use unordered_set ffs. JESUS CHRIST
Two Sum: Use unordered_map as inserting nums[i], if m.count(target - nums[i])
appear in map, we found a solution O(n), O(n)
Using two pointer make it O(n), O(1).
Maximum Sum Subarray: Single loop, 2 global var: maxSum and cur. If we come up a
new number, curSum = max(curSum +nums[i], nums[i]), then compare maxSum =
max(curSum, maxSum). The idea is: Once we come up to a number, see if we want to
add it, or we want to start over at that number. The checkpoint is a negative value
Maximum Product Subarray: Same idea as maximum sum subarray. But we have another
check: 0. 0 turns separate arrays into chunks. negative value flips the minimum to
maximum. So we need to keep check of curMin as well. Single loop, keep track of 3
global var: maxSum, curMax, curMin.
- tmp = curMax (we store this for curMin calculation, since curMax change)
- curMax = max({nums[i], nums[i]*curMax, nums[i]*curMin})
- curMin = min({nums[i], nums[i]*tmp, nums[i]*curMin})
- maxSum = max({maxSum, curMax, curMin}) // THen return maxSum in the end of
function.
Subsets I (Leetcode 78): [] [1] -> [] [1] [] [1] -> [] [1] [2] [1,2]. So the
algorithm is nested loop. Outer loop keep track of new element (nums[i]). Inner
loop do 2 things: mimic & double the res size, add new element to the half (mimic)
size of the res. Repeat.
Subsets II: the formula: j = repeatCount/(repeatCount+1). This start the new mimic
portion, works for 0
[1,2,2]: [] [1] [2] [1,2] -> [] [1] [2] [1,2] [2] [1,2] -> [] [1] [2] [1,2]
[2,2] [1,2]
[1,2,2]: [] [1] [2] [1,2] [2,2] [1,2] -> [] [1] [2] [1,2] [2,2] [1,2] [2,2]
[1,2] -> [] [1] [2] [1,2] [2,2] [1,2] [2,2,2] [1,2,2,2]
Move Zeroes: Give array, move all 0s to the right, keep everything in order
-> Solution: Partitionning algorithm (usually used in quick sort, ..) (MUST
KNOW THIS)
- Initialize left = 0; then make a forloop i from 0 to container.size()
- If the condition of the left side satisfies, swapValue(left, i), then left+
+
-> Solution 2: Smart ass but simple
- Record index of last time we see a non-zero: lastIndex
- Loop from i to container.size, if see non-zero, swap(nums[i],
nums[lastIndex]), lastIndex++;
- Later on, loop again from lastIndex to end, fills with 0s.
Linked List:
Reverse Linked List: Just becareful with operations. Use pre, head and cur.
Reassign head at the end. O(n), 1
QUEUE:
994. Rotting Oranges: Multi source BFS. Initialize level = 0. Remember: Inside
while (!q.empty()), save q.size() first before iterating thorugh level. q.pop() &
q.front() inside for loop that is inside while loop. Near the end of while loop,
check if current queue size: q.size() > 0, increase level.
Graph:
Number of Island: Loop each index of 2d-array, use BFS on an island, mark visited
(either in place or new array). O(m.n), O(m.n)
Binary:
Reverse Bits: Tricks: Get the ith digits: digit = n>>i & 1; adding digits to the
end: a*2 + digit; or a<<1 + digit. O(n)
Missing numbers: Trick: XOR same number gets 0, XOR 0 with a number get a number.
So XOR everything together, meaning nums[i] ^ i (i from 1 to n) then XOR res^n give
you the result. Other solution is just do n(n+1)/2 - sum(nums[i from 0 to size]) =
res.
Matrix:
Rotate Image:
Method 1: Do spiral interval, shift a row to column, store the placement
value first though.
Method 2: Do a transpose, then do a reverse (horizontally or vertically)
depends on flip 90 clockwise or cc.
Recursion:
Merge Sort: Divide array by 2, base case is array size = 1, then merge the two sub-
array.
Tree:
Invert Binary tree: DFS, change left to right, recursive root->left, recursive
root->right, return root
K-smallest element in BST: , k global (by reference), when k == 0, save Res global.
When done, return res. Modify the function call to pass by reference.
Same Tree: if (!p & q) || (!q && p) return false; if (!p && !q) return true;
else return p->val == q->val && isSameTree(p->left, q->left) && isSameTree(p-
>right, q-right)
Subtree of Another Tree:
O(NxM): traverse O(N), check for everynode isSametree O(M). O(NxM)
BackTrack
79. Word Search:
-> O(R*C * 4*(3^L)) dfs backtrack solution. R=row, C=col, L=word.length().
3^L b/c we dont go back to visited node. 4*(3^L) because 4 directions.
- For(rows) for(cols), if (dfs(board, word, rows, col, 0)) return true
// Sub problem start at 0 index of word.
- If (pos == word.size()) return true; // Base case, found match
- If out of bound, return false; // Out of Bound
- If (board[row][col] != word[pos]) return false; // We dfs but at this
point there's no matching word
- else we OR the result of dfs(4directions) to bool furtherSearch search
while marking current one visited.
- At the end, mark current one back to original: board[row][col] = word[pos];
then return furtherSearch;
DP:
55. Jump Game I:
-> O(N^N): if pos == nums.size() - 1, flag = true. For (i in len), dfs(nums,
pos+i).
->
-> // O(N) greedy solution:
// Calculate from the end. If the i^th position can reach the goal, update
goal.
// Return goal == 0 // This means we can reach the final destination from
the beginning