Advertisement

Remove Duplicate Letters - LeetCode 316 Solution

Remove Duplicate Letters - Complete Solution Guide

Remove Duplicate Letters is LeetCode problem 316, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.

Problem Statement

Given a string s , remove duplicate letters so that every letter appears once and only once. You must make sure your result is the smallest in lexicographical order among all possible results. Example 1: Input: s = "bcabc" Output: "abc" Example 2: Input: s = "cbacdcbc" Output: "acdb" Constraints: 1 <= s.length <= 10^4 s consists of lowercase English letters. Note: This question is the same as 1081: https://leetcode.com/problems/smallest-subsequence-of-distinct-characters/

Detailed Explanation

The problem asks us to remove duplicate letters from a given string `s` such that each letter appears only once. Additionally, we need to ensure that the resulting string is the smallest in lexicographical order among all possible results. Lexicographical order refers to dictionary order. The input is a string `s` consisting of lowercase English letters. The output should be the string with unique characters in lexicographical order.

Solution Approach

The solution uses a stack and a greedy approach. It iterates through the input string, and for each character, it checks if the character is already in the stack. If not, it compares the character with the character at the top of the stack. If the current character is smaller than the character at the top of the stack, and the character at the top of the stack appears later in the string (based on its last occurrence), then the character at the top of the stack is removed. This process is repeated until the stack is empty, or the conditions for removing the top character are not met. Finally, the current character is added to the stack. A 'seen' set is used to track characters currently in the stack.

Step-by-Step Algorithm

  1. Step 1: Create a `last` array/map to store the last occurrence index of each character in the string `s`.
  2. Step 2: Initialize an empty stack to store the candidate substring.
  3. Step 3: Initialize a `seen` set/array to track the characters currently in the stack.
  4. Step 4: Iterate through the string `s` from left to right.
  5. Step 5: For each character `c`, if `c` is already in `seen`, skip to the next character.
  6. Step 6: While the stack is not empty, `c` is smaller than the top of the stack, and the index `i` of `c` is less than the last occurrence of the top of the stack in `s`, remove the top of the stack from the stack and `seen`.
  7. Step 7: Add `c` to the stack and `seen`.
  8. Step 8: After iterating through the entire string, the stack contains the desired substring. Join the characters in the stack to form the result string.

Key Insights

  • Insight 1: The crucial insight is that we can use a stack to maintain a candidate substring and a greedy approach to decide whether to keep or remove characters from the stack to maintain lexicographical order.
  • Insight 2: We need to know the last occurrence of each character in the input string to make informed decisions about removing characters from the stack. This allows us to ensure that we don't remove a character prematurely if it will appear later in the string.
  • Insight 3: The `seen` set/array is critical to prevent re-adding letters to the stack, ensuring each letter appears only once.

Complexity Analysis

Time Complexity: O(n)

Space Complexity: O(1)

Topics

This problem involves: Stack, Greedy, String, Monotonic Stack.

Companies

Asked at: ByteDance, DRW, Expedia, FactSet, Goldman Sachs.