给你一个字符串 s
,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。
示例 1:
输入:s = "bcabc"
输出:"abc"
示例 2:输入:s = "cbacdcbc"
输出:"acdb"
提示:
1 <= s.length <= 10^4
s 由小写英文字母组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-duplicate-letters
【贪心】
使得得到的字符串字典序最小:遇到 s[i+1] < s[i]时,若后面还存在字符ch = s[i],则将字符s[i]去除,留到后面再加入,若不存在只能保留
只需用vis记录已收纳哪些字符来保证不重复,vis已收纳则直接跳过,逻辑重心留在遍历并贪心的保持字典序
public String removeDuplicateLetters(String s) {
int[] count = new int[26];
//vis记录输出串里有哪些字符
boolean[] vis = new boolean[26];
char[] ss = s.toCharArray();
for (char c : ss) {
count[c - 'a']++;
}
StringBuilder sb = new StringBuilder();
for (char c : ss) {
if (!vis[c - 'a']) {
//尽可能删除输出串的逆序字符
while (sb.length() > 0 && sb.charAt(sb.length() - 1) > c) {
//后面没有这个更大字符的替换字符了
if (count[sb.charAt(sb.length() - 1) - 'a'] <= 0) {
break;
} else {
vis[sb.charAt(sb.length() - 1) - 'a'] = false;
sb.deleteCharAt(sb.length() - 1);
}
}
sb.append(c);
vis[c - 'a'] = true;
}
//count记录后面还有多少字符
count[c - 'a']--;
}
return sb.toString();
}