PTA 字符串最小化去重 JAVA

编写程序,删除输入的字符串中的重复字符,使得余下的字符串最小(按字符的字典排列比较规则),且余下的字符在原来字符串的相对位置保持不变。 说明:1)字符串中均为小写字母;2)字符串长度在9998以内。

输入样例1:

一个由小写字母组成的字符串:

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 }

 

 

posted @ 2021-12-29 21:56  Imepeto  阅读(363)  评论(0)    收藏  举报