Using a Robot to Print the Lexicographically Smallest String

medium stack greedy suffix minimum

Problem

A robot holds an empty string t (a stack). Repeatedly either remove the first character of s and push it onto t, or pop the last character of t and write it on paper. Return the lexicographically smallest string the robot can write.

Inputs = "bdda"
Output"addb"
Push all of "bdda" onto t, then pop everything: a, d, d, b → "addb".
Inputs = "bac"
Output"abc"
Push b, a; pop a, b → "ab"; push c; pop c → "abc".

def robot_with_string(s):
    n = len(s)
    suffix_min = [0] * (n + 1)
    suffix_min[n] = chr(127)            # sentinel larger than any letter
    for i in range(n - 1, -1, -1):
        suffix_min[i] = min(s[i], suffix_min[i + 1])
    stack, out = [], []
    for i, ch in enumerate(s):
        stack.append(ch)               # push s[i] onto t
        while stack and stack[-1] <= suffix_min[i + 1]:
            out.append(stack.pop())    # write top of t to paper
    while stack:
        out.append(stack.pop())
    return "".join(out)
function robotWithString(s) {
  const n = s.length;
  const suffixMin = new Array(n + 1);
  suffixMin[n] = "{";                  // sentinel after 'z'
  for (let i = n - 1; i >= 0; i--) {
    suffixMin[i] = s[i] < suffixMin[i + 1] ? s[i] : suffixMin[i + 1];
  }
  const stack = [], out = [];
  for (let i = 0; i < n; i++) {
    stack.push(s[i]);                  // push s[i] onto t
    while (stack.length && stack[stack.length - 1] <= suffixMin[i + 1]) {
      out.push(stack.pop());           // write top of t to paper
    }
  }
  while (stack.length) out.push(stack.pop());
  return out.join("");
}
String robotWithString(String s) {
    int n = s.length();
    char[] suffixMin = new char[n + 1];
    suffixMin[n] = '{';                       // sentinel after 'z'
    for (int i = n - 1; i >= 0; i--) {
        char c = s.charAt(i);
        suffixMin[i] = c < suffixMin[i + 1] ? c : suffixMin[i + 1];
    }
    Deque<Character> stack = new ArrayDeque<>();
    StringBuilder out = new StringBuilder();
    for (int i = 0; i < n; i++) {
        stack.push(s.charAt(i));              // push s[i] onto t
        while (!stack.isEmpty() && stack.peek() <= suffixMin[i + 1])
            out.append(stack.pop());          // write top of t
    }
    while (!stack.isEmpty()) out.append(stack.pop());
    return out.toString();
}
string robotWithString(string s) {
    int n = s.size();
    vector<char> suffixMin(n + 1);
    suffixMin[n] = '{';                       // sentinel after 'z'
    for (int i = n - 1; i >= 0; i--)
        suffixMin[i] = min(s[i], suffixMin[i + 1]);
    string stack, out;
    for (int i = 0; i < n; i++) {
        stack.push_back(s[i]);                // push s[i] onto t
        while (!stack.empty() && stack.back() <= suffixMin[i + 1]) {
            out.push_back(stack.back());      // write top of t
            stack.pop_back();
        }
    }
    while (!stack.empty()) { out.push_back(stack.back()); stack.pop_back(); }
    return out;
}
Time: O(n) Space: O(n)