day5 HJ23 删除字符串中出现次数最少的字符

317 阅读2分钟

题目来源: HJ23 删除字符串中出现次数最少的字符

题目描述:

image.png

思路

将字符串的每个字符与97相减后,由于每个字符的ASCII码不同,所以根据相减的结果的不同,使得对应下标的数组值进行+1的操作(数组通过初始化所有初始值都为0),最后将数组值最小且不等于0的进行删除

具体实现:

01    public static void main(String[] args){
02        Scanner scanner = new Scanner(System.in);
03        String str = scanner.nextLine();
04       int ints[] = new int[26];  //默认初始值为0,因为题目只有小写字母,所以26就足够了
05        for(int i = 0; i < str.length(); i ++){
06            char charAt = str.charAt(i);
07            ints[charAt-97] ++;  //与a的ASCII值97相减后,对应下标的数组值+1
08        }
09        int temp = Integer.MAX_VALUE;    //用于查找最少次数的中间量
10        char ch1 = 0;
11        for (int i = 0; i < 26; i++) {
12            if (ints[i] != 0 && ints[i] < temp) {
13                temp = ints[i];     //最少的出现次数
14            }
15        }
16        for(int i = 0; i < 26;i++){
17            if(ints[i] == temp){    //将与最小出现次数相同的都删除(ints[i]的值变为0)
18                ints[i] = 0;
19            }
20        }
21        for(int i = 0; i < 26;i++){
22            if(ints[i] == 0){       //将已经删除的字符(i == 0),从字符串中用""替换掉,完成删除
23                char ch = (char) (i + 'a');       
24                str = str.replace(ch + "", "");
25            }
26        }
27        System.out.println(str);
28    }
  • 时间复杂度:O(n) ——进行了遍历的操作
  • 空间复杂度:O(n) ——引入了额外的数组

思路杂记

1.对于代码中用于查找出现的最小次数的中间量temp,初值给的是Integer.MAX_VALUE,这是int数据类型的最大取值数,这样就可以保证ints[i]temp进行第一次比较时,不会发生ints[i]>=temp的情况。

例如若temp=0,而这样所有ints[i]>=temp,就无法得出字符串中字符出现的最小次数了;若temp=1,如果存在出现一次的字符,那么顾名思义最小的出现次数就是1,即ints[i]==1的时候,就会发生ints[i]>=temp的情况,这样(ints[i] != 0 && ints[i] < temp)的结果是FALSE,temp就不存在被1赋值的情况,也就无法得出正确的最小出现次数...以此类推

2.对于查找最小次数的for循环,12~14行的if代码,可以修改为

    if (ints[i] != 0 ) {
        temp = Math.min(temp,ints[i]);
    }

这样可能对于功能的理解更直观

3.对于上述代码最后一个for循环,功能是将出现最小次数的字符从字符串中最终完成删除,而这个功能最初的代码是

    for(int i = 0; i < 26;i++){
        if(ints[i] != 0){                //想要一个个输出
            ch1 = (char) (i + 97);
            for(int j =0;j<ints[i];j++){
                System.out.print(ch1);
            }
        }
    }

但是这个代码没有考虑相同的字符不相邻的情况,比如输入的字符是asdsdsdsa,输出的结果就是dddssss,但是正确的结果应是sdsdsds,明显看出输出的结果还存在一个问题,那就是d与s位置的前后关系都不同了

4.对于最后一个for循环中使用的replace()方法,java中有两种替换方法,public String replace(char oldChar, char newChar) public String replace(CharSequence target, CharSequence replacement),这里使用的第二种,自JDK 1.5起就添加了第二种替换方法。 可以用下面的两段代码,体验一下这两个替换方法。

 public class ReplaceExample1{  
        public static void main(String args[]){  
            String s1="lidihuo is a very good website";  
            String replaceString=s1.replace('i','e');  
            System.out.println(replaceString);  
        }  
    }

    public class ReplaceExample2{  
        public static void main(String args[]){  
            String s1="my name is khan my name is java";  
            String replaceString=s1.replace("is","was");  
            System.out.println(replaceString);  
        }  
    }

    public class ReplaceExample3 {  
        public static void main(String[] args) {  
            String str"oooooo-hhhh-oooooo";  
            String rs = str.replace("h","s");  
            System.out.println(rs);  
            rs = rs.replace("s","h");  
            System.out.println(rs);  
        }  
    }

值得注意的是,替换从字符串的开头朝末尾执行,例如,用 "b" 替换字符串 "aaa" 中的 "aa" 将生成 "ba" 而不是 "ab"

    public static void main(String args[]){
        String s1="aaa";
        String replaceString=s1.replace("aa","b");
        System.out.println(replaceString);
    }