问题描述
在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符的位置。若为空串,返回-1。位置索引从0开始.
示例:
输入:sabcdsdf
输出:1
算法描述
定义一个52个元素的整型数组aCount,初始化为0,每个字母(大小写)依次对应一个,记录字母出现的次数;
定义一个52个元素的整型数组aPos,初始化为-1,每个字母(大小写)对应一个,记录字母第一次出现的位置;
每次遍历一个到字母,aCount数组里对应字母加1,判断目前aCount数组里该字母的计数是否为1,是则在aPos里记录字母出现位置;若已不是1,则将位置设为-1.
最后遍历aPos,不是-1同时又最小的那个就是第一个只出现一次的字符的位置。
运行时间O(n)
代码实现
class Solution {
public:
int FirstNotRepeatingChar(string str) {
//空串返回-1
if (str == "") return -1;
// 前26个元素代表小写字母,后26个元素代表大写字母
int aCount[52], aPos[52];
for (int i = 0; i < 52; i++) {
aCount[i] = 0;
aPos[i] = -1;
}
// 开始遍历
for (int i = 0; i < str.length(); i++) {
int pos = 0;
if (str[i] >= 'a' && str[i] <= 'z') {
pos = str[i] - 'a';
}
else {
pos = str[i] - 'A' + 26;
}
aCount[pos] += 1;
if (aCount[pos] == 1) {
aPos[pos] = i;
}
else {
aPos[pos] = -1;
}
}
// 最后判断aPos数组
int result = -1; // 如果没有,就返回 -1
for (int i = 0; i < 52; i++){
if (aPos[i] != -1) {
if (result == -1)
result = aPos[i];
else
result = result < aPos[i] ? result : aPos[i];
}
}
return result;
}
};