题目
截图自官方
代码
class Solution {
// 没想出来
// 贪心,解法2,空间复杂度,注意为O(1),时间复杂度O(n),因为while循环受字母表总数影响,是常数级的。
// 思路:就是让结果首字母的字典序最小,其位置之后还必须有原s出现过的所有字符。
// 先记录每个出现的字符出现的最后位置
// 遍历字符串,如果当前字符字典序小于栈首的,且栈首字符的最后出现位置在当前字符之后,则从栈中弹出,将当前字符压入。
// 这里需要注意的问题就是对后来出现的重复字符的处理如abcda,不出的话结果会是abcda
// abcabcd
// public String removeDuplicateLetters(String s) {
// Map<Character,Integer> last=new HashMap();
// // 记录每个字符最后出现的位置
// for(int i=0;i<s.length();i++){
// last.put(s.charAt(i),i);
// }
// Stack<Character> temp=new Stack();
// // 记录已添加的,防止添加重复的
// Set<Character> seen=new HashSet();
// for(int i=0;i<s.length();i++){
// if(!seen.contains(s.charAt(i))){
// while(!temp.empty()&&temp.peek()>s.charAt(i)&&i<last.get(temp.peek())){
// char t=temp.pop();
// // 注意这里
// seen.remove(t);
// }
// temp.push(s.charAt(i));
// seen.add(s.charAt(i));
// }
// }
// // 第一次看到对栈这样的操作。
// // 这样可以把栈中的元素从栈底为首的顺序取出来(像队列)
// StringBuilder res=new StringBuilder(temp.size());
// for(Character c:temp){
// res.append(c);
// }
// return res.toString();
// }
// 解法一,递归解法。大思路是一样。时间:O(n),空间O()
public String removeDuplicateLetters(String s) {
int[] count=new int[26];
for(int i=0;i<s.length();i++){
count[s.charAt(i)-'a']++;
}
int min=0;
for(int i=0;i<s.length();i++){
// 寻找字典序最小的字符
if(s.charAt(i)<s.charAt(min)){
min=i;
}
// 当前字符只有该位置有一个了,必须结束寻找,以min为首了。
if(--count[s.charAt(i)-'a']==0){
break;
}
}
// 注意api
return s.length()==0?"":s.charAt(min)+removeDuplicateLetters(s.substring(min+1).replaceAll(s.charAt(min)+"",""));
}
}
笔记