题目:
在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).
分析:
其实主要还是hash,利用每个字母的ASCII码作hash来作为数组的index。
首先,需要定义一个长度为58的数组来存储每个字母出现的次数。58的理由如下:
因为区分大小写,大写A-Z对应的ASCII码为65-90,小写的a-z对应的ASCII码值为97-122,一共26*2=52个英文字母,大写的Z和小写的a之间有91~96共6个位置的空缺,所以需要用一个58长度的数组来存储每个字母出现的次数。
而每个字母的index=int(word)-65,比如g=103-65=38,而数组中具体记录的内容是该字母出现的次数,最终遍历一遍字符串,找出第一个数组内容为1的字母就可以了,时间复杂度为O(n)
代码:
int FirstNotRepeatingChar(string str) {
int a[58]={0};//动态生存期的元素初始化是随机的,赋初值为0
for(int i=0;i<str.length();i++)
{
a[(int)str[i]-65]+=1;
}
for(int i=0;i<str.length();i++)
{
if(a[(int)str[i]-65]==1)
{
return i;
}
}
return -1;
}
Tips
-
数组的声明
数组属于自定义数据类型,因此在使用前首先要进行类型声明。声明一个数组类型,应该包括以下几个方面。
(1)确定数组的名称
(2)确定数组元素的类型
(3)确定数组的结构(包括数组维数,每一维的大小等)
数组类型声明的一版形式为:数组类型 标识符【常量表达式1】【常量表达式2】
数组中元素的类型是由"数据类型"给出,可以是整型、浮点型等基本类型,也可以是结构体、类等自定义类型。数组名称有“标识符”表示。常量表达式1指定了数组每一维的大小
例如:int a[10];
表示a为int型数组,有10个元素:a[0]~a[9],可以用于存放有10个元素的整数序列。本题通过分析可以确定数组的长度为58,类型为int,因此可以直接采用
int a[58]声明数组 -
数组的初始化
数组初始化就是在声明数组时给部分或全部元素赋初值。当指定的初值个数小于数组大小时,剩下的数组元素会被赋予0值。若定义数组时没有指定任何一个元素的初值,对于静态生存期(static修饰) 的数组,每个元素仍然会被赋予0值;但对于 动态生存期(幽冥局部生存期对象,其诞生于声明点,结束于声明所在块执行完毕之时)的数组,每个元素的初值都是不确定的。本题中声明的数组用于记录每个字符在字符串中出现的次数,因此应设初值为0值,且声明的数组属于动态生存期的数组,因此应在声明的同时进行初始化,即
int a[58]={0};。

本文介绍了一种利用ASCII码和哈希表高效查找字符串中首次出现的唯一字符的方法,通过定义一个58长度的数组来存储各字母出现次数,实现O(n)时间复杂度的查找。

823

被折叠的 条评论
为什么被折叠?



