↓Skip to main content
  1. LeetCode/

LeetCode 402: Remove K Digits

·2 mins· ·
LeetCode Medium String Stack Greedy Monotonic-Stack
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: medium First Attempt: 2022-11-17

  • Submissions: Wrong Answer ×2 → Runtime Error → Accepted ×2

Approach
#

To minimize the result, earlier digits matter most (Stack Template 4). Keep an increasing stack from left to right: while the current digit is smaller than the top and deletions remain (k > 0), pop the top, since a smaller digit in an earlier position always wins. If k remains afterward, delete from the end (the rest increases, so the end is largest). Strip leading zeros and return "0" if nothing is left.

My Attempts
#

  • Attempt 1 guessed “take the minimum among the first k + 1 digits”, which is not the right greedy: "22", k = 1 returned "22".
  • Switching to “delete the first digit larger than its successor”, the bound i != len(num) - 1 was insufficient and i overran after deletions (IndexError), with no leading-zero stripping. i < len(num) - 1 plus str(int(num)) passed, though rebuilding the string per deletion costs O(nk).

Solution
#

class Solution:
    def removeKdigits(self, num: str, k: int) -> str:
        st = []
        for d in num:
            while k and st and st[-1] > d:
                st.pop()
                k -= 1
            st.append(d)
        if k:
            st = st[:-k]
        return "".join(st).lstrip("0") or "0"

Complexity
#

Time O(n), space O(n).

Mistakes to Avoid
#

  • If k remains after the scan, delete from the end, as in "22", k = 1.
  • Strip leading zeros and return "0" for an empty result.
  • Rebuilding the string after each deletion is O(n²).

Interview Explanation
#

Earlier digits matter most, so I keep an increasing stack and pop a larger top whenever deletions remain, delete any leftover count from the end, and strip leading zeros. Each digit enters and leaves once, so time is O(n).

Related

LeetCode 227: Basic Calculator II
·2 mins
LeetCode Medium Math String Stack
LeetCode 227 note: read whole numbers, and at each operator apply the previous one: + and - push the number (negated for -), * and / combine with the top
LeetCode 71: Simplify Path
·2 mins
LeetCode Medium String Stack
LeetCode 71 note: split on /, skip empty pieces and ., pop on .. (never above root), push other names, and join with /
LeetCode 324: Wiggle Sort II
·2 mins
LeetCode Medium Array Divide-and-Conquer Greedy Sorting
LeetCode 324 note: sort, split into a small half and a large half, reverse each, and interleave with small values at even indices and large ones at odd indices
LeetCode 334: Increasing Triplet Subsequence
·2 mins
LeetCode Medium Array Greedy Longest-Increasing-Subsequence
LeetCode 334 note: keep the smallest first and the smallest second that has something smaller before it; any number above second completes a triplet
LeetCode 397: Integer Replacement
·2 mins
LeetCode Medium Dynamic-Programming Greedy Bit-Manipulation Memoization
LeetCode 397 note: even numbers are always halved; for odd numbers try +1 and -1 with memoized recursion, since n is too large for an n-sized array
LeetCode 435: Non-overlapping Intervals
·2 mins
LeetCode Medium Array Dynamic-Programming Greedy Sorting
LeetCode 435 note: minimum removals = total minus the maximum kept; sort by right end and greedily keep the one ending earliest