【字符串】第一个只出现一次的字符

题目描述

在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).(从0开始计数)

输入
“google”
返回值
4


哈希法

这是我第一个想到的方法,利用一个哈希表,遍历一次字符串,将字符作为哈希键值,字符的下标作为value,若字符重复出现,则将其value变成10002(最大值);最后遍历一次value的值,返回最小的下标,若最小的下标为10002,则全为重复的字符返回-1

public int FirstNotRepeatingChar(String str) {
    
    
	HashMap<String, Integer> hashMap = new HashMap<>();
	for (int i = 0; i < str.length(); i++) {
    
    
	    String s = String.valueOf(str.charAt(i));
	    if (!hashMap.containsKey(s)) hashMap.put(s, i);
	
	    else hashMap.put(s, 10002); // repeate char
	}
	int min = 10002;
	for (int v : hashMap.values())
	    if (v < min) min = v;
	return min == 10002 ? -1 : min;
}

优化方法

因为字符均为大小写字母a~zA~Z,其ASCII码分别为97~12265~90,共52个字符,为了方便索引,我们开辟一个58空间的数组,因为122-65+1=58,这样可以通过字符的ASCII码减去65直接得到数组的下标进行操作,数组用来存储每个字符出现的次数,遍历一次字符串记录每个字符出现的次数,最后再遍历一次字符串看哪个字符最先出现的次数为1。这个方法利用了字符的ASCII码,并且使用58空间的数组来记录52个字符出现的次数,用多余的6个空间换取时间,十分灵活巧妙。这种方法也是哈希的思想,但只需要数组来实现即可,因为键值是有限的,所以有时候并不需要总使用哈希表。

public int FirstNotRepeatingChar(String str) {
    
    
    int count[] = new int[58];
    for (int i = 0; i < str.length(); i++)
        count[(int) str.charAt(i) - 65]++;
    for (int i = 0; i < str.length(); i++)
        if (count[(int) str.charAt(i) - 65] == 1)
            return i;
    return -1;
}

猜你喜欢

转载自blog.csdn.net/weixin_43486780/article/details/113806477