题目描述:
给定一个字符串 s
,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1
。
方法一:哈希表
创建一个哈希表,遍历字符串中的字符,并在哈希表中查找该字符,如果没有则将字符对应的数字填入哈希表的key中,并将value设为1. 如果在哈希表中找到了该字符,则将该字符的value+1
创建完成后,再次遍历字符串字符,并依次到哈希表中查找,如果哈希表中该字符的value值为1,则返回该字符的索引,否则继续查找。如果遍历完字符串仍没有找到value值为1的字符,则返回-1.
其中需要注意的是查找哈希表的函数 HASH_FIND_INT(all, &c, cur),其中c是要查找的key值,给函数的参数必须是其地址。
typedef struct hashTable
{
int key;
int value;
UT_hash_handle hh;
}Hash;
int firstUniqChar(char * s){
Hash *all = NULL;
int len = strlen(s);
for(int i=0; i<len; ++i)
{
int c = *(s+i);
Hash *cur=NULL;
HASH_FIND_INT(all, &c, cur);
if(cur!=NULL)
{
cur->value++;
}
else
{
cur = (Hash*)malloc(sizeof(Hash));
cur->key =*(s+i);
cur->value = 1;
HASH_ADD_INT(all, key, cur);
}
}
for(int i=0; i<len; ++i)
{
int new = *(s+i);
Hash *temp;
HASH_FIND_INT(all, &new, temp);
if(temp->value==1)
{
return i;
}
}
return -1;
}
方法二:创建一个有26元素的数组
此方法更加简便,且执行方法1基本需要20ms以上,方法二则可将时间控制在10ms以内。
题中已经给了提示说字符中只有小写字母,所以可先创建一个有26个元素的数组来记录每个字母出现的次数。初始化数组令每一个元素都为0,遍历字符串将每个字符存在的次数赋值给数组后,再次遍历字符串,并查找数组中记录的次数,如果次数为1则直接返回该字母的索引。
int firstUniqChar(char * s){
int letters[26];
memset(letters, 0, sizeof(int)*26);
int len = strlen(s);
for(int i=0; i<len; ++i)
{
letters[s[i]-'a']++;
}
for(int i=0; i<len; ++i)
{
if(letters[s[i]-'a']==1)
{
return i;
}
}
return -1;
}
第二种方法🐂~