给一个全是小写字母的字符串str,删除多余字符,使得每种字符只保留一个,并且让最终结果字符串字典序最小。
基于已存在的和后面的字符做加入,删除操作
依次取当前字符,若栈为空或者大于栈顶字符(且栈中不存在该字符),就放入
小于栈顶元素,就查看栈顶元素在字符串后面有没有存在的,有的话就弹出,直到栈为空或字符串没有存在相同元素;然后放入该新字符。
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.*; public class Main { public static Scanner sc = new Scanner(System.in); public static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); public static void main(String[] args) throws Exception { String s = sc.nextLine(); // String s = "dbcacbca"; int n = s.length(); char[] chars = s.toCharArray(); // 统计出现次数 int[] cnt = new int[255]; for(int i=0;i<n;i++){ cnt[chars[i]] ++; } // 统计是否当前被使用给过了 boolean[] vis = new boolean[255]; // 收集结果的栈 Stack<Character> sta = new Stack<>(); for(int i=0;i<n;i++){ cnt[chars[i]] --; // 用一个少一次 if(sta.isEmpty() && vis[chars[i]] == false){ sta.push(chars[i]); vis[chars[i]] = true; }else { Character topChar = sta.peek(); if(chars[i] > topChar && vis[chars[i]] == false){ sta.push(chars[i]); vis[chars[i]] = true; } if(chars[i] < topChar && vis[chars[i]] == false){ while (!sta.isEmpty() && sta.peek() > chars[i] && cnt[sta.peek()] > 0){ vis[sta.peek()] = false; sta.pop(); } sta.push(chars[i]); vis[chars[i]] = true; } } } // 输出结果 char[] ans = new char[sta.size()]; int ansIndex = ans.length - 1; while(!sta.empty()){ ans[ansIndex --] = sta.peek(); sta.pop(); } System.out.println(ans); } } /* dbcacbca dabc */