Smallest Subsequence of Distinct Characters in Python

Suppose we have a text, we have to find the lexicographically smallest subsequence of text that contains all the distinct characters of text exactly once. So if the input is like “cdadabcc”, then the output will be “adbc”.
To solve this, we will follow these steps −
Define a stack st, two maps last_o and considered, they are initially blank
for i in range length of text – 1 down to 0if text[i] is not present in last_o −last_o[text[i]] := iconsidered[text[i]] := falsei := 0while i < length of textif stack has no elementspush text[i] into stackconsidered[text[i]] := trueincrease i by 1otherwise stack top > text[i] and considered[text[i]] is falseif last_o[stack top] > iconsidered[stack top element] := falsepop from stackOtherwiseconsidered[tex[i]] = trueinsert text[i] into stackincrease i by 1otherwise when stack top element < temp[i] and considered[text[i]] = falseinsert text[i] into stackconsidered[text[i]] := trueincrease i by 1otherwise increase i by 1
if text[i] is not present in last_o −last_o[text[i]] := iconsidered[text[i]] := false
last_o[text[i]] := i
considered[text[i]] := false
i := 0
while i < length of textif stack has no elementspush text[i] into stackconsidered[text[i]] := trueincrease i by 1otherwise stack top > text[i] and considered[text[i]] is falseif last_o[stack top] > iconsidered[stack top element] := falsepop from stackOtherwiseconsidered[tex[i]] = trueinsert text[i] into stackincrease i by 1otherwise when stack top element < temp[i] and considered[text[i]] = falseinsert text[i] into stackconsidered[text[i]] := trueincrease i by 1otherwise increase i by 1
if stack has no elementspush text[i] into stackconsidered[text[i]] := trueincrease i by 1
push text[i] into stack
considered[text[i]] := true
increase i by 1
otherwise stack top > text[i] and considered[text[i]] is falseif last_o[stack top] > iconsidered[stack top element] := falsepop from stackOtherwiseconsidered[tex[i]] = trueinsert text[i] into stackincrease i by 1
if last_o[stack top] > iconsidered[stack top element] := falsepop from stack
considered[stack top element] := false
pop from stack
Otherwiseconsidered[tex[i]] = trueinsert text[i] into stackincrease i by 1
considered[tex[i]] = true
insert text[i] into stack
increase i by 1
otherwise when stack top element < temp[i] and considered[text[i]] = falseinsert text[i] into stackconsidered[text[i]] := trueincrease i by 1
insert text[i] into stack
considered[text[i]] := true
increase i by 1
otherwise increase i by 1
return all of the elements of stack as string in reverse order
Let us see the following implementation to get better understanding −
class Solution(object):
   def smallestSubsequence(self, text):
      """
      :type text: str
      :rtype: str
      """
      stack = []
      last_o = {}
      considered = {}
      for i in range(len(text)-1,-1,-1):
         if text[i] not in last_o:
            last_o[text[i]] = i
            considered[text[i]] = False
      print(last_o)
      i = 0
      while i < len(text):
         print(stack,i,text[i])
         if len(stack) == 0:
            stack.append(text[i])
            considered[text[i]] = True
            i+=1
         elif stack[-1]>text[i] and considered[text[i]] == False:
            if last_o[stack[-1]]>i:
               considered[stack[-1]]=False
               stack.pop()
            else:
               considered[text[i]] = True
               stack.append(text[i])
               i+=1
         elif stack[-1]<text[i] and considered[text[i]] == False:
            stack.append(text[i])
            considered[text[i]] = True
            i+=1
         else:
            i+=1
      return "".join(i for i in stack)
"cdadabcc"
"adbc"