To get the lexicographically smallest subsequence with all distinct characters, we use a stack to build the answer. We greedily remove characters from the stack if a smaller character is available later and hasn’t been used yet.
classSolution {
public: string smallestSubsequence(string s) {
vector<int> last(26);
for (int i =0; i < s.size(); ++i) last[s[i]-'a'] = i;
vector<bool> used(26);
string ans;
for (int i =0; i < s.size(); ++i) {
char c = s[i];
if (used[c-'a']) continue;
while (!ans.empty() && ans.back() > c && last[ans.back()-'a'] > i) {
used[ans.back()-'a'] = false;
ans.pop_back();
}
ans.push_back(c);
used[c-'a'] = true;
}
return ans;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
funcsmallestSubsequence(sstring) string {
last:= make([]int, 26)
fori, c:=ranges { last[c-'a'] = i }
used:= make([]bool, 26)
ans:= []byte{}
fori:=0; i < len(s); i++ {
c:=s[i]
ifused[c-'a'] { continue }
for len(ans) > 0&&ans[len(ans)-1] > c&&last[ans[len(ans)-1]-'a'] > i {
used[ans[len(ans)-1]-'a'] = falseans = ans[:len(ans)-1]
}
ans = append(ans, c)
used[c-'a'] = true }
return string(ans)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
classSolution {
public String smallestSubsequence(String s) {
int[] last =newint[26];
for (int i = 0; i < s.length(); ++i) last[s.charAt(i)-'a']= i;
boolean[] used =newboolean[26];
StringBuilder ans =new StringBuilder();
for (int i = 0; i < s.length(); ++i) {
char c = s.charAt(i);
if (used[c-'a']) continue;
while (ans.length() > 0 && ans.charAt(ans.length()-1) > c && last[ans.charAt(ans.length()-1)-'a']> i) {
used[ans.charAt(ans.length()-1)-'a']=false;
ans.deleteCharAt(ans.length()-1);
}
ans.append(c);
used[c-'a']=true;
}
return ans.toString();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
classSolution {
funsmallestSubsequence(s: String): String {
val last = IntArray(26)
for (i in s.indices) last[s[i]-'a'] = i
val used = BooleanArray(26)
val ans = StringBuilder()
for (i in s.indices) {
val c = s[i]
if (used[c-'a']) continuewhile (ans.isNotEmpty() && ans.last() > c && last[ans.last()-'a'] > i) {
used[ans.last()-'a'] = false ans.deleteAt(ans.length-1)
}
ans.append(c)
used[c-'a'] = true }
return ans.toString()
}
}
1
2
3
4
5
6
7
8
9
10
11
12
classSolution:
defsmallestSubsequence(self, s: str) -> str:
last = {c: i for i, c in enumerate(s)}
used = set()
ans = []
for i, c in enumerate(s):
if c in used: continuewhile ans and ans[-1] > c and last[ans[-1]] > i:
used.remove(ans.pop())
ans.append(c)
used.add(c)
return''.join(ans)