class Solution:
    def customSortString(self, S: str, T: str) -> str:
        # time O(T+S) space O(T)
        cnt = collections.Counter(T)
        res = []
        for c in S:
            if c in cnt:
                res.append(c*cnt.pop(c))
        for c,v in cnt.items():
            res.append(c*v)
        return ''.join(res)

Follow up if T or S or both T & S are really big. time complexity may be O(N^2),how to optimize?

class Solution:
# time O(NlgN) N= len(T)
    def customSortString(self, S: str, T: str) -> str:
        # step1: dictionary, get char: index ; 
        d = {}
        for idx,val in enumerate(S):
            d[val] = idx
        # step2: sort by index as weight, for non prioritized charto check 
        res = sorted(T, key = lambda k: d.get(k,len(T)+ord(k)))
        # step3: return string
        return ''.join(res)