Smallest Subsequence of Distinct Characters in Python

PythonServer Side ProgrammingProgramming

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 0
    • if text[i] is not present in last_o −
      • last_o[text[i]] := i
      • considered[text[i]] := false
    • i := 0
    • while i < length of text
      • if stack has no elements
        • push text[i] into stack
        • considered[text[i]] := true
        • increase i by 1
      • otherwise stack top > text[i] and considered[text[i]] is false
        • if last_o[stack top] > i
          • considered[stack top element] := false
          • pop from stack
        • Otherwise
          • considered[tex[i]] = true
          • insert text[i] into stack
          • increase i by 1
      • otherwise when stack top element < temp[i] and considered[text[i]] = false
        • 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 −

Example

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)

Input

"cdadabcc"

Output

"adbc"
raja
Updated on 05-Mar-2020 07:02:11

Advertisements