day3 HJ10 字符个数统计

190 阅读2分钟

题目来源: HJ10 字符个数统计

题目描述:

image.png

思路:

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

具体实现:

    public static void main(String[] args){
    Scanner scanner = new Scanner(System.in);
    String str = scanner.nextLine();
    int ints[] = new int[500];  //默认初始值为0
    for(int i = 0; i < str.length(); i ++){
        char charAt = str.charAt(i);
        ints[127-charAt] ++;  //与127相减后,对应下标的数组值+1
    }
    int top = 0;
    for(int i = 0; i < 500; i ++){ 
        if(ints[i] != 0){ //将数组值不为0的个数进行统计
            top++;
        }
    }
    System.out.println(top);
}
  • 时间复杂度:O(n) ——进行了遍历的操作
  • 空间复杂度:O(n) ——引入了额外的数组

思路杂记

1.初始化数组int ints[] = new int[500];,一开始粗心写成了char[] chars = new char[500];,而char类型定义的数组,初始值就不是默认为0,而是0对应的字符,使用UTF8字符集的话,给出的结果是 image.png 同时,由于java 中的数组初始值都为零,若填充其他值,可以用Arrays.fill方法,但只能填充一个一维数组,多维数组还得用循环。

    int arr[] = new int[10];
    Arrays.fill(arr,Integer.MIN_VALUE);

2.若将数组值不为0的个数进行统计的代码,稍加修改,也可以求字符串中出现次数最多的字符,改为 if(ints[i] > top)top = ints[i];,便求出了出现最多的次数,将每次对应的i记录下来,便可反求对应的字符

    int top = 0;
    char ch1 = 0;
    for (int i = 0; i < 500; i++) {
        if (ints[i] > top) {
            top = ints[i];     //出现的次数
            ch1 = (char) (127 - i);  //出现次数所对应的字符
        }
    }

3.当然了,上面的第2点,是在区分大小写的前提下,因为大小写字母的ASCII值不同,如果不区分大小写的话,可以先进行统一小写的操作,在day2 计算某字符出现次数这篇文章中有使用到这个操作

思路拓展之利用HashMap

借鉴于该文章

  • 直接利用Java中的java.util.HashMap来进行存储,HashMap的具体存储原理以及源码分析可以参考文章 JDK 1.8 HashMap 源码解析

  • Java中LinkedHashMap(JDK1.8之后)中每个节点上都是链表,类似于邻接表,当邻接表的链表长度超过8时,会转换成红黑树。

  • 同时LinkedHashMap的默认初始容量为16.

import java.util.Scanner;
import java.util.HashMap;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        HashMap<Integer,Boolean> hashMap = new HashMap<>();
        String str = in.nextLine();
        char c;
        for(int i = 0; i < str.length(); i++){
            c = str.charAt(i);
            hashMap.putIfAbsent(c+0,true);
        }
        System.out.println(hashMap.keySet().size());
    }
}
  • 时间复杂度:O(n)—— 根据LinkedHashMap原理,LinkedHashMap的默认初始容量为16,而最坏情况下有127个(回车符不会出现),邻接表的链表长度超过8时会最终转化成黑红树,但是在Hash函数平均分布的情况下不可能产生红黑树,因此最坏的情况下总时间为8n,时间复杂度为O(n)

  • 空间复杂度:O(1)