Implement stack variants and path-sum check
Company: TikTok
Role: Machine Learning Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates data-structure design and algorithmic skills including constant-time stack variants (min/max stacks), online algorithms for streaming median computation, upward-only path-sum reasoning in trees, and the ability to state time/space trade-offs and handle edge cases.
MinStack — O(1) getMin
Constraints
- 1 <= number of operations <= 10^4
- -10^9 <= x <= 10^9
- pop, top, getMin are only called on a non-empty stack
- The first op is always the constructor 'MinStack'
Examples
Input: (['MinStack','push','push','push','getMin','pop','top','getMin'], [[],[-2],[0],[-3],[],[],[],[]])
Expected Output: [None, None, None, None, -3, -3, 0, -2]
Explanation: Push -2,0,-3. getMin -> -3. Pop -3. top -> 0. getMin -> -2.
Input: (['MinStack','push','getMin','top','pop'], [[],[5],[],[],[]])
Expected Output: [None, None, 5, 5, 5]
Explanation: Single element: min, top, and pop all return 5.
Input: (['MinStack','push','push','push','getMin','pop','getMin','pop','getMin'], [[],[3],[3],[1],[],[],[],[],[]])
Expected Output: [None, None, None, None, 1, 1, 3, 3, 3]
Explanation: Duplicate minimums: after popping 1, the min correctly restores to 3.
Hints
- Keep a second stack that stores, at each level, the minimum of all elements at or below it.
- On push, the new running minimum is min(x, previous running minimum).
- Because the auxiliary stack mirrors the main stack, getMin is just its top.
MaxStack — peekMax and popMax
Constraints
- 1 <= number of operations <= 10^4
- -10^9 <= x <= 10^9
- pop, top, peekMax, popMax are only called on a non-empty stack
- popMax removes the topmost occurrence when the maximum is duplicated
Examples
Input: (['MaxStack','push','push','push','top','popMax','top','peekMax','pop','top'], [[],[5],[1],[5],[],[],[],[],[],[]])
Expected Output: [None, None, None, None, 5, 5, 1, 5, 1, 5]
Explanation: Stack [5,1,5]. top -> 5. popMax removes the TOP 5 -> 5, leaving [5,1]. top -> 1. peekMax -> 5. pop -> 1. top -> 5.
Input: (['MaxStack','push','peekMax','popMax','push','top'], [[],[7],[],[],[3],[]])
Expected Output: [None, None, 7, 7, None, 3]
Explanation: Push 7. peekMax/popMax -> 7 (now empty). Push 3. top -> 3.
Input: (['MaxStack','push','push','push','popMax','popMax','peekMax'], [[],[2],[2],[2],[],[],[]])
Expected Output: [None, None, None, None, 2, 2, 2]
Explanation: All equal maxima: popMax returns 2 twice, peekMax still 2.
Input: (['MaxStack','push','push','push','push','popMax','top'], [[],[1],[3],[3],[1],[],[]])
Expected Output: [None, None, None, None, None, 3, 1]
Explanation: Stack [1,3,3,1]. popMax removes the top-most 3 (index 2), leaving [1,3,1]. top -> 1.
Hints
- The simplest correct approach scans the list for the maximum on demand.
- For popMax with duplicates, scan from the TOP downward and delete the first match so you remove the occurrence closest to the top.
- To reach O(log n), pair an ordered multiset (TreeMap of value -> stack of node ids) with a doubly linked list so you can delete an interior node in O(1) once located.
Streaming median (data stream)
Constraints
- 1 <= number of operations <= 10^5
- -10^9 <= x <= 10^9
- findMedian is only called after at least one addNum
- Even-sized median is the average of the two middle elements (return a float)
Examples
Input: (['MedianFinder','addNum','addNum','findMedian','addNum','findMedian'], [[],[1],[2],[],[3],[]])
Expected Output: [None, None, None, 1.5, None, 2.0]
Explanation: After {1,2}: median (1+2)/2 = 1.5. After {1,2,3}: median = 2.0.
Input: (['MedianFinder','addNum','findMedian'], [[],[42],[]])
Expected Output: [None, None, 42.0]
Explanation: Single element: median is that element as a float.
Input: (['MedianFinder','addNum','addNum','addNum','addNum','findMedian'], [[],[5],[15],[1],[3],[]])
Expected Output: [None, None, None, None, None, 4.0]
Explanation: Sorted {1,3,5,15}: median (3+5)/2 = 4.0.
Input: (['MedianFinder','addNum','addNum','findMedian','addNum','addNum','findMedian'], [[],[-1],[-2],[],[-3],[-4],[]])
Expected Output: [None, None, None, -1.5, None, None, -2.5]
Explanation: Negatives: {-2,-1} median -1.5; {-4,-3,-2,-1} median (-3+-2)/2 = -2.5.
Hints
- Maintain two heaps: a max-heap of the smaller half and a min-heap of the larger half.
- Keep their sizes balanced so they differ by at most 1; the small half holds the extra element when the count is odd.
- If sizes are equal the median is the average of both heap tops; otherwise it is the top of the larger (small) half.
Tree path sum — upward-only path
Constraints
- 0 <= number of nodes <= 10^4
- All node values are positive integers (1 <= value <= 10^9)
- parent[i] is a valid index < i's... not required, but -1 marks the root
- 1 <= target <= 10^14
- An empty tree returns false
Examples
Input: ([5, 3, 8, 1], [-1, 0, 0, 1], 9)
Expected Output: True
Explanation: Node 3 (value 1) -> node 1 (value 3) -> node 0 (value 5) sums to 1+3+5 = 9.
Input: ([5, 3, 8, 1], [-1, 0, 0, 1], 8)
Expected Output: True
Explanation: Node 1 (value 3) -> node 0 (value 5) sums to 8; also single node 2 has value 8.
Input: ([5, 3, 8, 1], [-1, 0, 0, 1], 7)
Expected Output: False
Explanation: No upward path sums to 7.
Input: ([10], [-1], 10)
Expected Output: True
Explanation: Single node equals target.
Input: ([10], [-1], 5)
Expected Output: False
Explanation: Single node value 10 cannot reach 5 (positive values only).
Input: ([], [], 0)
Expected Output: False
Explanation: Empty tree -> false.
Input: ([2, 4, 6, 8], [-1, 0, 1, 2], 20)
Expected Output: True
Explanation: Skewed chain: node 3 (8) -> node 2 (6) -> node 1 (4) -> node 0 (2) = 20.
Input: ([2, 4, 6, 8], [-1, 0, 1, 2], 100)
Expected Output: False
Explanation: Target larger than the total sum of all nodes (20).
Hints
- An upward path is just a node plus a contiguous run of its parents — try each node as the path's lower endpoint.
- Walk from a start node up through parent pointers, accumulating the sum.
- Because all values are positive, the running sum is monotincreasing — stop early (break) once it exceeds target.