Algo Flashcards
- Sliding Window Median
Remember:
- Calc median must check left.size() - nRemovingLeft vs. right.size() - nRemovingRight not just only left.size() and right.size()
- Using 2 priority queues: add to left must compare to move it to right if needed
- LRU Cache
- Using DLinkedList for the rank. When moving rank to top must keep the same instance so that we don’t need to update keyToRanks.put(key, newRank)
- removeElement must update prev and next to null at the end
- Serialize and Deserialize N-ary Tree
Remember to add “+” at the end of the node string as a termination notation, otherwise, when reading digits it read the one of the next node string e.g.
1+0(ended)1+0: two-node with 0 children but when reading it because the first node with “01” = 1 child
- Construct Binary Tree from Inorder and Postorder Traversal
- Use inorderIndices of num -> index to split (start, end) in inorder array
- Only build retVal.right then retVal.left if its size > 0
- Using stack to store postorder
min & max & sum of array of ints
IntStream.of(ints).min().getAsInt()
IntStream.of(ints).max().getAsInt()
IntStream.of(ints).sum()
- Design Search Autocomplete System. Methods:
- AutocompleteSystem(String[] sentences, int[] times) {}
- List input(char c) {}
Using Trie and add times: Map to each node
- Maximum Sum of 3 Non-Overlapping Subarrays
- -> must find indices of arrays, not just the sum
- DP with memorization
- Loop through the cache to trace back e.g. find first, second …
- Using dfs(nums, end,…) instead of dfs(nums, start,…) to get the first match
- Delete Node in a BST
How to implement removeSmallest(TreeNode parent, TreeNode node): int
Go to left most node ultil node.left == null:
parent. left = parent.left == node ? node.right : parent.left;
parent. right = parent.right == node ? node.right : parent.right;
- Stickers to Spell Word
- dfs(int[] target, int[][] stickers, cache)
- remember dfs can return -1. Must check. Do not do like this:
Math.min(retVal, 1 + dfs(newTarget, stickers, cache)
- Longest Valid Parentheses
e. g. ()) -> 2
DP
- Best Time to Buy and Sell Stock IV
max k transactions
- Use int[][] transactions = new int[k][2]; // list of [min-price, max-profit so far]
- Initialize transactions[j][0] = prices[0];
- Start from idx = 1
- Best Meeting Point
- Loop through all rows and columns to collect house rows, house columns
- Find the median of these sets of rows and columns separately
- Remove Invalid Parentheses
return all longest valid strings
- Two options for each open, close: keep or remove
- Remember to check and stop if opens < closes
- Remember to:
resultBuilder.append(ch)
call dfs
remove last char in resultBuilder
- Minimum Window Substring
Input: s = “ADOBECODEBANC”, t = “ABC”
Output: “BANC”
- Calc freqs for t
2. Move pointer idx, increase currentFreqs, try to move left pointer, decrease currentFreqs to make idx - left smallest
- Minimum Window Subsequence
Input: s1 = “abcdebdde”, s2 = “bde”
Output: “bcde”
MUST maintain the order
- build closest array e.g. closest[j][0] the nearest ‘a’ to the left
- go from right to left of s1, find s1[idx] = s2 last char
- go from right to left of s2, find nextId = clostest[nextIdx - 1][ch - ‘a’]
Important notes: - use nextIdx - 1
- check nextIdx - 1 >= 0
- Palindrome Pairs
words[i] + words[j] is a palindrome.
Find all (i, j)
- create suffixes and prefixes set
- for each word check: suffix then prefix
- remember the case: ab, ba will appear twice because of 2. For case word == suffix/prefix, only pick in “check suffix” ignore in “check prefix”
- Data Stream as Disjoint Intervals
e.g. add 1, 1
add 2, 2
add 3, 3
return 1,3
use TreeMap
TreeMap methods, what throws an exception if empty?
- higherKey, lowerKey, floorKey, ceilingKey: null if empty
2. firstKey, lastKey: exception if empty
- LFU Cache
- using Rank i.e DLinkedList with prev, next, keys, freq
- JUST check case by case e.g. key does not exist, new freq does not exist, etc.
do not need to do abstract here - must be fast, this is very long
- Robot Room Cleaner
- use visit(robot, row, col, direction, cache)
2. directions must be consistent e.g. {0, -1} then {1, 0} then {0, 1} then {-1, 0}
- Zigzag Conversion
- if numRows == 1: return
- 2 cases:
a. first + last row
b. normal row
- Largest Divisible Subset
e.g. [1,2,3,4,5,6,7,8,9]
return [1,2,4,8]
- sort nums
- dp to calc largestSubsets[i]
- remember largestSoFar: int and largestNum in this largest so far
- trace back: right -> left
finding = largestSoFar, num = largestNum
find: nums[i] % num == 0 && largestSubsets[i] == finding then update:
*** num = nums[i]
- Prefix and Suffix Search
i. e. search(String prefix, String suffix): return largest idx
- using prefix & suffix Trie having Trie.wordIndices
- in search find prefixIndices and suffixIndices
- remember to reverse suffix before searching
- must use prefixIndices.get(i).equals(…) instead of ==
- Basic Calculator III
e. g. (1+2)/3
- 2 stacks: nums and opts
- remember idx++: not applied for reading operands
- rules:
a. meet num: eval if top = * or /
b. meet + or -: eval if top = + or -
c. meet ): eval ultil seeing (
d. after seeing (, must eval because of this case:
2 * (1+2)
- Sliding Puzzle
e. g. [[1, 2, 3], [4,0,5]] -> 1 swap to make [[1,2,3],[4,5,0]]
- must use BFS instead of normal dfs i.e. using seen to keep track of the path. This dfs with the depth of (mn)! call stack causes 2**(mn)! time complexity
- using int swaps to count the number of steps
- Swim in Rising Water
i. e. with raining, grid[i][j] is the height of the cell
- can only go from cell 1 to cell 2 if the height of 2 cells + water is the same
- use Math.max(top[0], maxHeight of 2 cells) for nei cell
- Sliding Window Maximum
k window, return max in the window for each move
- using dq/queue to achieve O(N)
2. store idx in dq instead of value
- Shortest Subarray with Sum at Least K
with negative nums
Note: use PriorityQueue of sum also works
1. using treeMap.put(preSum, last idx)
2. find floorEntry of currentSum - k, if found
keep trying then remove all keys before this floorKey
3. key here is (for both neg and positive shortest subarray problem): if 1 start point can pair with current idx, we can remove it because the next idx2 if can pair, the length idx2 - start is already > idx - start
- Super Egg Drop
n floors, k eggs –> how many moves
- using dp[moves][eggs] how many floors can be covered with this number of moves & eggs
- dp[moves][eggs] = 1 + dp[moves - 1][eggs] + dp[moves-1][eggs-1]
- remember to catch base case moves - 1 <= 0, eggs = 0 or 1
895. Maximum Frequency Stack pop the max freq, if same freq, pop the last added one e.g. push: 2 1 2 1 pop: 1 2 1 2
Observation: pop val, freq will decrease by 1 so for sure the freq - 1 will exist
- freqToVals: Map>
- maxFreq
- valToFreqs: current freq
- Number of Music Playlists
k: before can repeat the song e.g. k = 2: 1 2 3 1
input: k, songs, goal: playlist size
- dp: dp[songs][goal] = dp[songs - 1][goal - 1] * songs + dp[songs][goal - 1] * (songs - k)
- base cases: songs == goals && songs == k + 1
for: songs == k + 1: e.g. 3 songs, k = 2: always repeat the pattern
1 2 3 1 2 3… doesn’t matter the value of goals
- Binary Tree Cameras
Camera can cover itself, parent and children
- int minCamera(TreeNode node, boolean withCamera, boolean covered)
- consider case by case e.g. if withCamera, if not withCamera but covered…
- remember to cache
- Number of Ways to Paint N × 3 Grid
using 3 colors, no 2 cells having the same color
- long dfs(int rows, int colorsLastRow)
- colorsLastRow can be 2 or 3
- count(prevColors, colors): just use 3 for-loops
- Combination Sum
find all combinations sum up to target
e.g. [2,3,6,7] target = 7 result = [[2,2,3],[7]]
- backtracking, no fancy algo here
2. must ask interviewer about duplication constraint
- Longest Substring with At Most K Distinct Characters
- using left, right. Init = 0
- for each loop while right < length
a. add new s[right]
b. move left until unique chars <= k
c. update retVal
d. right++
- Count subarrays with K Different Integers
a. read problem 340. Longest Substring with At Most K Distinct Characters
b. result = atMost(nums, k) - atMost(nums, k - 1)
- Largest Component Size by Common Factor
e. g. [20,50,9,63] –> 2 groups 20, 50 and 9, 63
- for each num loop through [2, Math.sqrt(num)] as
common
- use UF.union(num, common) and (num, num / common) if num % common == 0
- for each num, using UF.findParents to count items in each group
- Interval List Intersections
when checking to move, must compare point[1] values instead of point[0] values
- Number of Submatrices That Sum to Target
- calc prefixSum[row][col] must use: row Sum and prefix[row - 1][col] but NOT global sum
- loop with (r1, r2, c) to have N^3, not N^4
- Valid Palindrome III
e. g. remove at most k letters to make a palindrome
- using check(left, right) <= k to have N^2 instead of N^3 with (left, right, removing)
- Divide Chocolate
e.g. split into n subarray, select the one with min sweetness
? max sweetness can have
- same as 410
- Maximal Square
i. e. area of the biggest square with all 1
- N^3 solution:
a. calc prefixOnes: how many ones in the row from right to this cell
b. try to go down - dp[row][col] = 1 + min(dp[row + 1][col], dp[row][col + 1], dp[row + 1][col + 1])
- Partition List
i. e. linked list, given x. Sort nodes so that < x in left, >= x in the right but maintain the original order
- preHead, head
- find preRight, right
- move from right.next, delete node.val < x, create node before right, after preRight
- Minimum Cost to Cut a Stick
range: 0 -> n, & list of cuts. cost of cut = length of the bar
- time: O(C ^ 3), C = number of cuts
2. cut(left, right, cuts)
- Search in Rotated Sorted Array II
with duplications
- check case nums[mid] < nums[right] case
a. check case to have left = mid + 1, the rest will be right = mid - 1 - else if nums[mid] > nums[right]
a. remember nums[mid] < target OR: ***target <= nums[right] - else: check nums[left] vs. target before left++
- Minimum Number of Days to Make m Bouquets
- Find the Smallest Divisor Given a Threshold
- Divide Chocolate
- Capacity To Ship Packages In N Days
- Koko Eating Bananas
- Minimize Max Distance to Gas Station
- Split Array Largest Sum
- binary search
a. createfeasible
function
b. choose left, right
How to detect binary search problems?
e.g. divide chocolate problem: chocolate bar, maximize the minimized sweetness pieces
- satisfy condition(k) is true then condition(k +1) is true
- min (max) the max(min) value
ref: https://leetcode.com/discuss/general-discussion/786126/python-powerful-ultimate-binary-search-template-solved-many-problems
- Kth Smallest Number in Multiplication Table
binary search:
- left = 1, right = m * n
- for each mid, loop through each row, count how many col with (row + 1) * (col + 1) <= mid
- Find K-th Smallest Pair Distance [Hard]
i. e. distance = abs(nums[i] - nums[j])
- sort nums
- binary search
- problem: in a sorted array, count how many pairs having distance <= mid?
- Count Different Palindromic Subsequences
i. e. s.length <= 1000, only contain letters a, b, c, d
- build prefix (nearest char to the right e.g. ‘a’) at i, suffix (nearest char to the left e.g. ‘a’)
- unique chars in range i, j
- Shortest Path Visiting All Nodes
w/: nodes <= 12
- using mask int to store all nodes visited e.g. node.mask | 1 «_space;neiId
- seen = Set of nei + neiMask
*1326. Minimum Number of Taps to Open to Water a Garden
tap at [i] can cover i - ranges[i] to i + ranges[i]
- for each tap, calculate minRange, maxRange it can cover
- build farCanReach[minRange] = max of all maxRange
- use jump game way to solve: jump(start, farCanReach, memo)
- Number of Ways to Arrive at Destination
w/: shortest ways only from 0 to n - 1
- dijkstra
2. in for-loop of nei: update timeByNodes and countByNodes
- The Maze II
w/: shortest distance from start to destination
- dijkstra, do not do dfs, bfs
2. add isValidRoll(current, direction) function
- Couples Holding Hands
w/: how many swaps to make couples sit side by side
- 2n seat –> n couches of 2 seats
- connect couches into cycle e.g.
(0, 3), (1, 4), (2, 5)
c1 -> c2 -> c3 -> c1: 3 points -> need 2 swaps
- Find K Pairs with Smallest Sums
w/: 2 sorted arrays
w/: 1439. Find the Kth Smallest Sum of a Matrix With Sorted Rows
- same as merge sort k sorted arrays
- init: nums1[0], nums2[j] with max j = k - 1
- poll from priority-queue and increase idx1 if < nums1.length
- for 1439. reuse prev = kSmallestPairs(prev, mat[idx], k)
- Insert Interval
- find intertionIdx by finding last interval with
interval[1] < newInterval[0]
- Graph Valid Tree
w/: undirected graph
- build graph with:
retVal.computeIfAbsent(edge[0], k -> new HashSet<>()).add(edge[1]);
retVal.computeIfAbsent(edge[1], k -> new HashSet<>()).add(edge[0]); - IMPORTANT: dfs must have both node and prev node to prevent case: 0 –> 1, 1 –> 0 because of 1.
- Shortest Path in a Hidden Grid
w/: GridMaster.{canMove(direction: char), move(direction)}
- dfs to explore the grid
- bfs to find shortest distance. IMPORTANT: must update seen right after queue.add to avoid duplicate
NOT: add seen after queue.removeLast()
- Find Peak Element
return index of any peak element
imagine that nums[-1] = nums[n] = -inf
- using binary search way
- leftCond, rightCond
- if not mid && leftCond –> go right, otherwise, go left
- Find a Peak Element II
Given: a matrix where no two adjacent cells are equal
- ref 162. Find a Peak Element
- find row with max value of mid col
- of nums[maxRow][midCol] < nums[maxRow][midCol - 1] –> find in left…
- Game of Life
if live: neiLives == 2 or 3 to maintain live
if dead: neiLives == 3 to be live
? infinite board
- IMPORANT: directions must not contain (0, 0)
- O(1): store val: (prevStatus + 1) * 10 + (newStatus + 1)
- infinite board: keep 3 rows in memory: current, above, below
- Longest Repeating Substring
e. g. “aabcaabdaab” -> 3 (“aab” repeated)
solution 1. dp(s, end1, end2, memo): O(N^2)
solution 2. generate all suffixes then sort. repeated substrings should be adjacent: O(NLogN)
- Cheapest Flights Within K Stops
- dijkstra algo
- check & add in for-nei loop
- number of stops = Math.max(0, nFlights - 1)
- keep lastVisits: map of city -> [cost, flights]. Update every valid step in 2.
- Longest String Chain
- remove each letter and check with words to build the graph –> L^2N where L is max length of word (otherwise buildGraph could take LN^2
- ? check time complexity
- Rank Teams by Votes
e. g. “AB”, “AB”, “BA” -> A first, B second…
- create Map with Team.votes: int[nTeams]
2. sort by all vote in Team.votes DESC, then Team.name ASC
- Open the Lock
- Graph, BFS
- Longest Substring with At Least K Repeating Characters
- longest substring with n unique chars, n from 1 to AZ
2. using start, end pointers
- Number of Equal Count Substrings
e. g. “aabb”, count = 2 –> 3: “aa”, “bb”, “aabb” as all substrings having number of uniq chars = 2
- nChars = 1 to AZ. Two solutions from here:
a. using fixed window size e.g. count * nChars
b. using start, end pointers, same as 395. Longest Substring with At Least K Repeating Characters
- Longest Subsequence Repeated k Times
n == s.length
2 <= n, k <= 2000
2 <= n < k * 8
- max number of chars = 7
- generate candidates for each length value from 1 to 7 & check if there’re k repeating times
- time complexity: worst case: 7 unique chars e.g. abcdef. O(N77!)
- Valid Parenthesis String
with (, ) and * = empty, open or close
- solution 1: using dp(s, idx, opens, closes). O(N^3)
- solution 2: using dp(s, idx, balance). O(N^2)
- solution 2: using minBalance, maxBalance
a. incr both if meet (
b. decr both if meet )
c. decr min, incr max if meet *
d. return false if maxBalance < 0
e. return minBalance == 0
- Paths in Maze That Lead to Same Room
e. g. number of cycles with 3 nodes
- build the graph
- loop through all edges and check if neiRooms1 and neiRooms2 share the same nei then retVal++
- retVal / 3 as each cycle counted 3 times
- Minimum Cost to Reach City With Discounts
Use maximum N discounts for the route to have cost / 2
- similar to 787. Cheapest Flights Within K Stops. use lastVisits to record the last cost and discount
- but got TLE
- Split BST
given a target, split BST into 2 trees: <= target, > target
- 30 lines, dfs
- Delete and Earn
pick j and delete j, nums[j] + 1, nums[j] - 1 get nums[j] point. Calc max point
- sort
2. dp
- Minimum Insertions to Balance a Parentheses String
e.g. need ‘(‘ pair with ‘))’. How many add ‘(‘ and ‘)’ needed to make the input balanced
Similar: https://leetcode.com/problems/minimum-add-to-make-parentheses-valid/
- int balance
- if ch == ‘)’, read all, if closes % 2 == 1, add 1. Decrease the balance while closes > 0, balance > 0
- before returning: retVal += balance * 2
- Minimum Swaps to Make Strings Equal
e. g. “xx” and “yy” –> swap s1[0] and s2[1] to have “yx” == “yx”
- loop through all chars, ignore all s1[idx] == s2[idx]
- count x1, y1 and x2, y2
- Imposible: x1 + x2 != y1 + y2 || (x1 + x2) % 2 == 1
- case “xx” and “yy” need 1 swap, “xy”, “yx” need 2 swaps
- -> x1 / 2 + y1 / 2 + (x1 % 2 == 1 ? 2 : 0)
- Score of Parentheses
(): 1
AB: A + B
(A): 2 * A
- using stack, add 0 if open
2. update retVal if “)” and the root level
- Wildcard Matching
with ?: match 1, *: match any
- 3 cases to match * e.g. skip both, skip in s, skip in p