剑指34.第一个只出现一次的字符
题目描述
在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).(从0开始计数)
思路
创建哈希表,键值key为字符,值value为出现次数。第一遍扫描:对每个扫描到的字符的次数加一;第二遍扫描:对每个扫描到的字符通过哈希表查询次数,第一个次数为1的字符即为符合要求的输出。
思路1:使用Java内置的HashMap
思路2:用数组代替Map。
考虑到要统计的字符范围有限,也可以使用整型数组代替 HashMap。ASCII 码只有 128 个字符,因此可以使用长度为 128 的整型数组来存储每个字符出现的次数。数组的下标相当于键值key,对应字符的ASCII码值;数组的值相当于哈希表的值value,用于存放对应字符出现的次数。
注意,如果有多个字符都出现了一次,返回第一个出现的字符(因此最后一次遍历是对字符串遍历)!!
解法1
import java.util.*; public class Solution { public int FirstNotRepeatingChar(String str) { if (str == null || str.length() == 0) return -1; HashMap<Character,Integer> map = new HashMap<>(); for (char c : str.toCharArray()){ map.put(c,map.getOrDefault(c,0)+ 1); } for (int i = 0; i < str.length(); i++) { if (map.get(str.charAt(i)) == 1) return i; } return -1; } }
解法2
import java.util.*; public class Solution { public int FirstNotRepeatingChar(String str) { if (str == null || str.length() == 0) return -1; int[] arr = new int[256]; Arrays.fill(arr,0); // 不初始化也能AC for (int i = 0; i < str.length(); i++) { arr[str.charAt(i)]++;// 很关键,字符的ASCII码 } for (int i = 0; i < str.length(); i++) { // 注意是对原字符串遍历,因为要返回第一个出现的字符 if (arr[str.charAt(i)] == 1) return i; } return -1; } }