PTA 字符串最小化去重 JAVA
一个由小写字母组成的字符串:
bbcaac
结尾无空行
输出样例1:
去除重复字符串后的最小的字符串:
bac
结尾无空行
输入样例2:
一个由小写字母组成的字符串:
cbacdcbc
结尾无空行
输出样例2:
去除重复字符串后的最小的字符串:
acdb
结尾无空行
这道题总共要做三件事,1.删除重复字符;
2.去重过程中不能打乱原先字符顺序;
3.在所有符合去重字符串的结果中,取字典序最小的那个为结果
(字典序是指两个字符串从第一个字母开始比,第一个不相同的字母更小的字符串字典序也就更小)
此题可以用单调栈
代码:
1 import java.util.Scanner; 2 import java.util.Stack; 3 public class test3 { 4 public static void main(String[] args) { 5 System.out.println("请输入:"); 6 Scanner scan = new Scanner(System.in); 7 String str = scan.next(); 8 scan.close(); 9 char[] c = str.toCharArray(); 10 Tools tool = new Tools(); 11 tool.Out(c); 12 13 } 14 15 } 16 class Tools{ 17 public void Out(char[] c) { 18 Stack<Character> stk = new Stack<>(); 19 boolean[] stkb = new boolean[26]; 20 //定义一个判断数组,来获取栈中有哪些字母 21 int[] count = new int[26]; 22 //定义一个计数器,累计字符串中出现的每个小写字母个数 23 for(char cha : c) { 24 count[cha - 'a']++; 25 } 26 for(char cha : c) { 27 count[cha - 'a']--; 28 //每遍历到一个字母,就在计数器中相应位置减1 29 if(stkb[cha - 'a']) continue; 30 //如果栈中有这个字母,就跳过 31 while(!stk.empty() && stk.peek() > cha ) { 32 //判断栈是否为空和当前字母字典序是否小于栈顶字母 33 if(count[stk.peek() - 'a'] >= 1) 34 //如果当前字母在后续字符串中还会出现,则可以去除 35 stkb[stk.pop() - 'a'] = false; 36 //将判断数组内对应字母位置改为false,即不存在栈内, 37 之后将字母弹出栈 38 else break;//如果是唯一的,就退出 39 } 40 stk.push(cha);//插入新字母 41 stkb[cha - 'a'] = true; 42 //将判断数组内对应字母改为true,即存在栈内 43 } 44 //下面为输出 45 StringBuilder stb1 = new StringBuilder(); 46 while(!stk.empty()) { 47 stb1.append(stk.pop());
48 } 49 stb1.reverse(); 50 //由于从栈传入StringBuilder后,顺序是颠倒的,所以需要反向一下 51 System.out.println(stb1); 52 } 53 }

浙公网安备 33010602011771号