去除重复字母
给定一个仅包含小写字母的字符串,去除字符串中重复的字母,使得每个字母只出现一次。需保证返回结果的字典序最小(要求不能打乱其他字符的相对位置)。
示例 1:
输入: "bcabc"
输出: "abc"
示例 2:
输入: "cbacdcbc"
输出: "acdb"
思路+代码+注释:
public String removeDuplicateLetters(String s) {
/*
思路:使用一个hashMap记录每个字母出现的次数,使用visited这个hashMap记录每个字母是否被添加过,然后遍历字符串中的字母
,字母的次数减1,如果字母被添加过说明安排妥当剩余个数-1,继续循环;如果字母没被添加过,那么和结果中的最后一个字母进行比较,如果结果的最后一个字母大并且次数大于0那么删除结果最后一个字母并设置为未添加,
添加遍历的字母并设置为已添加,如果结果的最后一个字母小那么直接添加遍历的字母并设置为已添加
*/
HashMap<Character,Integer> sNum=new HashMap<>();
HashMap<Character, Boolean> visited=new HashMap<>();
char[] chars=s.toCharArray();
for (char c:chars
) {
if (sNum.containsKey(c))
{
sNum.put(c,sNum.get(c)+1);
}else {
sNum.put(c,1);
}
}
Set<Character> set=sNum.keySet();
for (Character c:set
) {
visited.put(c,false);
}
List<Character> res=new ArrayList<>(set.size());
res.add('0');
for (int i = 0; i < chars.length; i++) {
char c=chars[i];
if (!visited.get(c))
{
char last=res.get(res.size()-1);
if (last>c)
{
if (sNum.get(last)>0)
{
res.remove(res.size()-1);
visited.put(last,false);
i--;
}else {
//添加完字母后,字母数量-1
sNum.put(c,sNum.get(c)-1);
res.add(c);
visited.put(c,true);
}
}
else if (last<c)
{
sNum.put(c,sNum.get(c)-1);
res.add(c);
visited.put(c,true);
}
}
//该字母已在合适的位置不用管,剩余数量-1即可
else {
sNum.put(c,sNum.get(c)-1);
}
}
StringBuilder sb=new StringBuilder();
for (int i = 1; i < res.size(); i++) {
sb.append(res.get(i));
}
return sb.toString();
}