Problem: 2050D - Digital string maximization
Language: python

Solution 1 (runtime: 202 ms):
from functools import *
from itertools import *
from collections import *
from math import *
from bisect import *
from heapq import *

def factors(n):
    i = 1
    res = []
    while i <= sqrt(n):
        if (n % i == 0):
            if (n / i == i):
                res.append(i)
            else:
                res.append(i)
                res.append(n//i)
        i = i + 1
    return res

def prime_factors(n):
    i = 2
    factors = []
    while i * i <= n:
        if n % i:
            i += 1
        else:
            n //= i
            factors.append(i)
    if n > 1:
        factors.append(n)
    return factors

def largest_prime_factor(n):
    i = 2
    while i * i <= n:
        if n % i:
            i += 1
        else:
            n //= i
    return n

def sieve(n):
    prime = [True for i in range(n+1)]
    p = 2
    while (p * p <= n):
        if (prime[p] == True):
            for i in range(p * p, n+1, p):
                prime[i] = False
        p += 1

    return prime

MOD=10**9+7
class Factorial:
    def __init__(self, MOD):
        self.MOD = MOD
        self.factorials = [1, 1]
        self.invModulos = [0, 1]
        self.invFactorial_ = [1, 1]
 
    def calc(self, n):
        if n <= -1:
            print("Invalid argument to calculate n!")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        if n < len(self.factorials):
            return self.factorials[n]
        nextArr = [0] * (n + 1 - len(self.factorials))
        initialI = len(self.factorials)
        prev = self.factorials[-1]
        m = self.MOD
        for i in range(initialI, n + 1):
            prev = nextArr[i - initialI] = prev * i % m
        self.factorials += nextArr
        return self.factorials[n]
 
    def inv(self, n):
        if n <= -1:
            print("Invalid argument to calculate n^(-1)")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        p = self.MOD
        pi = n % p
        if pi < len(self.invModulos):
            return self.invModulos[pi]
        nextArr = [0] * (n + 1 - len(self.invModulos))
        initialI = len(self.invModulos)
        for i in range(initialI, min(p, n + 1)):
            next = -self.invModulos[p % i] * (p // i) % p
            self.invModulos.append(next)
        return self.invModulos[pi]
 
    def invFactorial(self, n):
        if n <= -1:
            print("Invalid argument to calculate (n^(-1))!")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        if n < len(self.invFactorial_):
            return self.invFactorial_[n]
        self.inv(n)  # To make sure already calculated n^-1
        nextArr = [0] * (n + 1 - len(self.invFactorial_))
        initialI = len(self.invFactorial_)
        prev = self.invFactorial_[-1]
        p = self.MOD
        for i in range(initialI, n + 1):
            prev = nextArr[i - initialI] = (prev * self.invModulos[i % p]) % p
        self.invFactorial_ += nextArr
        return self.invFactorial_[n]
 
class Combination:
    def __init__(self, MOD):
        self.MOD = MOD
        self.factorial = Factorial(MOD)
 
    def ncr(self, n, k):
        if k < 0 or n < k:
            return 0
        k = min(k, n - k)
        f = self.factorial
        return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD

for _ in range(int(input())):
    nums = list(map(int, list(input())))

    for q in range(10):
        finish = 1
        for i in range(len(nums)-1, 0, -1):
            if nums[i]-1>nums[i-1] and nums[i]>0:
                finish = 0
                nums[i], nums[i-1] = nums[i-1], nums[i]-1
        if finish: break

    for q in range(10):
        finish = 1
        for i in range(len(nums)-1):
            if nums[i]<nums[i+1]-1 and nums[i+1]>0:
                finish = 0
                nums[i], nums[i+1] = nums[i+1]-1, nums[i]
        if finish: break
            
    
    print("".join(map(str,nums)))
    

Solution 2 (runtime: 1171 ms):

class LinkedList:
    def __init__(self, l):
        self.list = l
        self.len = len(l)
        self.next = [i+1 for i in range(self.len)]
        self.next[-1] = None
        self.prev = [i-1 for i in range(self.len)]
        self.prev[0] = None
        self.head = 0
        self.current = self.head
    
    def to_head(self):
        self.current = self.head
        
    def pop(self, i=None):
        if i == None:
            self.current = self.head
        else:
            self.current = i
        next_ = self.next[self.current]
        prev_ = self.prev[self.current]
        if self.len == 1:
            self.head=None  
        elif self.current == self.head:
            self.head = self.next[self.head]
            self.prev[self.head] = None
        elif next_ == None:
            self.next[prev_] = None 
        else:
            self.next[prev_] = next_
            self.prev[next_] = prev_
        self.len -= 1
        
    def to_next(self):
        self.current = self.next[self.current]
        
    def elem(self):
        return self.list[self.current]
    
    def print_(self):
        i = self.head
        data = []
        data_n = []
        while i != None:
            data.append(self.list[i])
            data_n.append(self.next[i])
            i = self.next[i]
        print(data, data_n)
    
        


t = int(input())
for k in range(t):
    s = LinkedList(list(map(int,list(str(input())))))
    res = ''
    n = s.len
    count_masked = 0
    i = 0
    #s.print_()
    while s.len > 0:
        s.to_head()
        cost=1
        max_v=s.elem()
        max_j=-1
        s.to_next()
        while 9 - (s.list[s.head] + cost) > 0 and s.current != None:
            if s.list[s.current] - cost > max_v:
                max_v = s.list[s.current] - cost
                max_j = s.current
            cost+=1
            s.to_next()
        if max_j != -1:
            res+=str(max_v)
            s.pop(max_j)
        else:
            res+=str(s.list[s.head])
            s.pop()
        #s.print_()
    print(res)