Leetcode Summary
Problems
Some assumptions and notations
- Space and time complexity does not include input and output.
n
denotes the input length unless noted otherwise.- In case of graph,
E
denotes the number of edges,V
number of vertices/nodes.
004 Median of Two Sorted Arrays binarysearch
- Time \(O(\log(\min(m, n)))\)
- Space \(O(1)\)
A very genius algorithm is detailed in this post Very concise O(log(min(M,N))) iterative solution with detailed explanation. We could generalize that algorithm to find the \(k\)th element of two sorted arrays in \(O(\log(\min(m,n,k)))\) time.
Let's assume \(k\) is 0-based.
- For one sorted array
A
of length \(n\), the \(k\)th element isA[k]
, which divides the original array into two parts:A[0..k-1]
andA[k..n-1]
, i.e., there are exactly \(k\) element on the left of \(k\)th element no greater thanA[k]
. For two sorted array
A
of length \(n\),B
of length \(m\), and \(n \geq m\), if we could find positionsp
,q
inA
andB
respectively such thatp
\(+\)q
\(= k\)A[p-1]
\(\leq\)A[p]
andA[p-1]
\(\leq\)B[p]
B[p-1]
\(\leq\)B[p]
andB[p-1]
\(\leq\)A[p]
Then we say
z = min(A[p], B[p])
will be the \(k\)th element since there are \(k\) element no greater thanz
. Note that this formulation applies to arrays with duplicates.Since
p
andq
can be determined from each other, we could do a binary search in the shorter arrayB
. TheC++
code is available gongzhitaao/oj.
014 Longest Common Prefix adhoc
\(k\) is the length of longest common prefix.
- Time \(O(nk)\)
- Space \(O(1)\)
015 3Sum 3sum
- Time \(O(n^2)\)
- Space \(O(1)\)
Sort the array first, then use two loops:
- outer one
i
ranges[0, n-3)
- inner one
j
starts fromi
,k
starts from the end,- if sum is greater than expected, move
k
left, - if sum is less than expected, move
j
right, - otherwise move
j
right andk
left - until they meet
- if sum is greater than expected, move
035 Search Insert Position binarysearch
- Time \(O(\log n)\)
- Space \(O(1)\)
See the C++
std implementation of upper_bound
or lower_bound
.
039 Combination Sum dfs
- Time Uncertain
- Space Uncertain
Not sure about the complexity of the problem. It is rather intricate to determine in general. The idea is simple, i.e., brutal force with DFS, trying every possible combination. Note that the problem states that the provides candidates is a set, so you do not have to worry about duplicates.
105 Construct Binary Tree from Preorder and Inorder Traversal bst
Same as Leetcode 106.
106 Construct Binary Tree from Inorder and Postorder Traversal bst
Time \(O(n^2)\) space \(O(1)\) or Time \(O(n)\) space \(O(n)\)
- The last one in post-order traverse is the parent.
- Find the position of the parent in the in-order traverse.
- Recursively construct the left and right children.
If we store in a hash map all the values' position in the in-order traverse, it runs in \(O(n)\) at the expense of \(O(n)\) space, otherwise it runs in \(O(n^2)\).
113 Path Sum II bfs dfs
- Time \(O(E+V)\)
- Space \(O(V)\)
BFS is more space expansive up to a constant factor.
115 Distinct Sub-sequences dp
- Time \(O(mn)\) where m is length of
s
, n length oft
. - Space \(O(mn)\)
Naive divide-and-conquer search fails due to time limit. This could be solved with DP.
Suppose \(d[i][j]\) holds the number of solution for t[0..i-1]
and s[0..j-1]
, then d[n][m]
is the final solution.
State transition: \[d[i][j] = \begin{cases} d[i][j-1] + d[i-1][j-1], & \text{if}\ \text{T}[i-1] = \text{S}[j-1] \\ 1, & \text{otherwise} \end{cases}\]
116 Populating Next Right Pointers in Each Node bfs
- Time \(O(E+V)\)
- Space \(O(1)\)
Two loops:
i
iterates "row"j
iterates each level and connects each node's children.
117 Populating Next Right Pointers in Each Node II bfs
- Time \(O(E+V)\)
- Space \(O(1)\)
Similar to Leetcode 116, but in addition, we need to keep track of each level's starting node.
120 Triangle dp
- Time \(O(n^2)\)
- Space \(O(n)\)
Dynamic programming. The sum
holds current sum, then the state transition for sum[i]
is sum[i] = min(sum[i-1], sum[i]) + triangle[i]
. Be careful to
- backup
sum[i-1]
. - initialize
sum
to be all maximum integer value except for the first one, which is initialized to 0.
163 Missing Ranges adhoc
- Time \(O(n)\)
- Space \(O(1)\)
Just iterate through the array. Watch out for edge cases, like empty array, boundary values.
166 Fraction to Recurring Decimal adhoc
- Time uncertain
- Space uncertain
Just perform long division. As for repeating fraction detection, if we come across the same remainder, then we have a repeating fraction from where remainder occurs first.
Edge cases: negative case, no negative sign when numerator is 0, no decimal point when no fraction part.
199 Convert Sorted List to Binary Search Tree bfs dfs
- Time \(O(E+V)\)
- Space \(O(V)\)
Search the tree following BFS or DFS.
- BFS, record the last element at every level.
- DFS, right-to-left in-order traverse, record the element whenever level increases.
200 Number of Islands bfs disjointset
- Time \(O(mn)\)
- Space \(O(mn)\)
Similar to Leetcode 305, we can use disjoint-set. Or we could do a BFS on each land position.
218 The Skyline Problem divideconquer
- Time \(O(n\log n)\)
- Space \(O(n)\)
Naive solution is to create skyline for each building and merge them one by one, which runs in \(O(n^2)\) when all buildings are disjoint.
Improved version is to use merge-sort idea, split the problem into two half problem and merge the solutions. How to merge sub-skylines? Similar to merge-sort, start from the first elements of two skylines, compare the X coordinates, pick the smaller one, height is maximum of current heights from both skylines. If the new height is the same as old one, do not insert it as it will result in a consecutive horizontal lines of equal height.
259 3Sum Smaller 3sum
- Time \(O(n^2)\)
- Space \(O(1)\)
Similar to Leetcode 015, we keep two pointer lo
and hi
in the inner loop. The critical observation is if nums[i] + nums[lo] + nums[hi] < target
, then any hi
in the range (lo, hi]
satisfies the condition.
280 Wiggle Sort sort
- Time \(O(n)\)
- Space \(O(1)\)
Let's suppose we are at position k
, array A[0..k]
are wiggle-sorted already.
- Case 1
k
is odd - If
A[k+1] <= A[K]
, no change needed. IfA[k+1] > A[k]
, after swappingA[k+1]
withA[k]
, we haveA[k-1] <= A[k] > A[k+1]
. SoA[0..k+1]
is wiggle-sorted. - Case 2
k
is even - Argument similar to the above.
So just sweep through the array, swap any two element that does not satisfy the wiggle condition.
286 Walls and Gates bfs dfs
- Time \(O(mn)\)
- Space \(O(mn)\)
Start from each gate, do a BFS or DFS to update the distance for each room.
288 Unique Word Abbreviation adhoc
- Time initialization \(O(n)\), query \(O(1)\)
- Space \(O(n)\)
The question is straightforward, however, beware of the definition of "being unique", i.e., either the word itself does not exist in the dictionary or its key does not exist if it is in the dictionary.
305 Number of Islands II disjointset
- Time \(O(k\log mn)\) actually this is the query time, not including the initialization time, which is \(O(mn)\).
- Space \(O(mn)\)
Simple application of disjoint-set. For each new land, first we make itself a set, then union with its neighbors, if any.
The initial count is 0, for each new land, first we make a set of its own, increment the count. Then whenever we successfully union it with one of its neighbors, decrement the count.
308 Range Sum Query 2D - Mutable bit
- Time \(O(\log n)\) for update and sum
- Space \(O(n^2)\)
2D binary index tree (Fenwick tree).
309 Best Time to Buy and Sell Stock with Cooldown dp
- Time \(O(n^2)\)
- Space \(O(n)\)
Adpated from @GWTW solution. For day k, there are four states.
- Have stock, do nothing
- Have stock, sell the stock
- Have no stock, do nothing
- Have no stock, buy the stock
Let a[k]
, b[k]
, c[k]
, d[k]
denote the maximum profit on day k ending in each of the four states respectively, P[k]
the stock price on day k. The final solution is max(b[n], c[n])
.
State transition:
a[k + 1] = max(a[k], d[k])
b[k + 1] = max(a[k], d[k]) + P[k + 1] - P[k]
c[k + 1] = max(b[k], c[k])
d[k + 1] = max(c - P[k + 1])
Iterate from day 0 and initial values are all zeros.
312 Burst Balloons dp
- Time \(O(n^3)\)
- Space \(O(n^2)\)
If we divide the problem by first explosion position, the subproblems are not independent. However if we divide the problem by last explosion position, then the subproblems are independent. Let v[i][j]
denote the max coin required in range (i,j)
where i
and j
are off-bound. The state transition function is
\[v[i][j] = \max_k(v[i][j], v[i][k]+v[k][j]+nums[i]\times nums[k]\times nums[j])\]
where, \(i < k < j\).
Similar to Floyd-Warshall algorithms we need three nested loops to update the value matrix v
and v[0][n+1]
is the final result.
And as a side note, based on the state transition function, we could see that v[i][j]
depends on values below and left.
315 Count of Smaller Numbers After Self bit mergesort
Let's forget about the binary index tree for now. The basic idea is simple.
- We maintain a counter array
count[]
which stores the count of each element. - Sort a copy of the original array to Get each element's position after being sorted, stored in a hash map
h[]
. - Then traverse the original list in reverse order.
- For each element
e
, we increment by 1 its countercount[h[e]]
. - Sum all the numbers in the range
count[0...h[e]-1]
gives the number of smaller elements aftere
.
- For each element
Now this is a classic binary indexed tree problem, update and query. In the actual implementation, we may not need the counter array at all. We only need the binary indexed array.
324 Wiggle Sort II sort
This is problem looks similar to Leetcode 280. However the algorithm is drastically different.
- Leetcode 280,
nums[0] <= nums[1] >= nums[2] <= nums[3]....
- Leetcode 324,
nums[0] < nums[1] > nums[2] < nums[3]...
In other words, for Leetcode 280, there are always solutions, while it's not true for this problem. For example, [2,2,2,4,3]
and [2,3,2,4,3]
. Both satisfy the wiggle sort condition, but only the latter satisfy the wiggle sort II condition.
Assume the problem is always solvable, we need to find the median of the array, and whatever smaller than the median goes to even positions and the rest goes to odd positions.
340 Longest Substring with At Most K Distinct Characters dp
- Time uncertain, it seems between \(O(n)\) and \(O(n^2)\).
- Space \(O(n)\)
Iterate through the array A
with two pointers, i
and j
. And hashmap[j]
contains the count of each character that appears in the longest substring ending at j
.
- If
A[j+1]
is in the hash map, increment the corresponding count. - If
A[j+1]
is not in the hash map, insert it into the hash map with count 1, and if the total size of the hash map is larger thank
, then incrementi
until the size of hash map is no larger thank
.
367 Valid Perfect Square binarysearch
- Time \(O(\log n)\)
- Space \(O(1)\)
The input limits to 32-bit integer, therefore,
- the running time is actually constant.
- be careful about overflow.
368 Largest Divisible Subset dp
First sort the array in ascending order. Let v[i]
denote the largest divisible subset ending with nums[i]
, the state transition function is
\[v[i] = \max_{v[i].length} \left\{v[i]\bigcup v[j] \,\middle|\, \forall\, nums[i] \equiv 0 \bmod{nums[j]}\right\}\]
388 Longest Absolute File Path dfs
- Time \(O(n)\)
- Space \(O(n)\)
The string is actually the output of DFS traversal of the directory tree. The \n
delimits the end of an item (directory/file) name, while \t
gives the current level of the item. Just simulate the DFS traversal, store the current path length (not counting the directory delimiter /
) at each node. When ever we reach a file, i.e., a leaf node, update the current max length.
394 Decode String dfs
Time and space are uncertain.
Expand the string in a DFS fashion, i.e., expand the inner most repeater first.
406 Queue Reconstruction by Height dp
- Time \(O(n^2)\)
- Space \(O(n)\)
Wherever we insert a shorter person has no influence on taller people. Therefor, sort the people by height in non-ascending order, breaking ties by k-value in ascending order. And we will have a independent subproblem. Suppose we have already have the first k
persons in a proper order, for the k+1
person with n
people in front of him, just insert it in position n
.
421 Maximum XOR of Two Numbers in an Array xor
- Time \(O(31n) = O(n)\)
- Space \(O(n)\)
The XOR has a property: if \(c = a\oplus b\), then \(b = c\oplus a\). This is widely used in swapping two numbers, i.e., \(x = x \oplus y, y = x \oplus y, x = x \oplus y\).
We construct the solution, \(s\), from most significant bit to the least, bit by bit. Let \(a_k = a \gg (31 - k)\) denote the \(k\) (0-based) most significant bits for the number \(a\). Suppose we have already determined \(s_k\), now we want to determine the \(s_{k+1}\).
- First \(s_{k+1} = s_{k} \ll 1\), i.e., appending 0 to the solution, and change it to 1 if we can using the following steps.
- For each element \(a\) in the array, store \(a_{k+1}\) in a hash table.
- For each element \(a\) in the hash table, if \(s_{k+1}\oplus 1\oplus a\) is also in the hash table, then we could set the current bit to 1, i.e., \(s_{k+1} = s_{k+1}\oplus 1\).