题目一:字符串中第一个只出现一次的字符
【在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写)】
方法一:自建简易hashTable
1、分析
(1)、一种思路是将每个字符分别与后面的字符进行比较,若没有与它相同的则就是该字符。这种方法的时间复杂度是
O
(
n
2
)
O(n^2)
O(n2)。可以采用令一种方法,使用空间换时间。创建一个数组用来存放每个字符出现的次数,同时将字符串与该数组之间建立映射关系。在统计完每个字符出现的次数之后,再遍历该字符串的时就可以得到每个字符出现的次数。这种方法需要两次遍历该字符串,时间复杂度为
O
(
n
)
O(n)
O(n) 。
(2)、在统计每个字符出现次数的时候,可以以字符所对应的 ASCll 码为统计数组中元素的下标,数组中则存放该 ASCll 码所对应字符出现的次数。因为 char 字符占一个字节,即8位二进制,其能表示的大小是
2
8
=
256
2^8=256
28=256 个字符,所以可以用一个长度为256的数组来保存统计的结果。
2、代码
class Solution {
public:
int FirstNotRepeatingChar(string str) {
int len=str.size();
if(len==0)
return -1;
const int tableSize=256;
int *hashTable=new int[tableSize];
// 第一次遍历统计每个字符出现的次数,并保存该次数在对应的位置上
for(int i=0;i<len;++i)
{
hashTable[str[i]]++;
}
// 第二次遍历查找出对应的元素
for(int j=0;j<len;++j)
{
if(hashTable[str[j]]==1)
{
return j;
}
}
return -1;
}
};
方法二:使用STL中的map
class Solution {
public:
int FirstNotRepeatingChar(string str) {
int len=str.size();
if(len<=0)
return -1;
map<char,int> m;
for(int i=0;i<len;++i)
{
m[str[i]]++;
}
for(int j=0;j<len;++j)
{
if(m[str[j]]==1)
return j;
}
return -1;
}
};
题目二:字符流中第一个只出现一次的字符
【请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。(如果当前字符流没有存在出现一次的字符,返回#字符)】
1、分析
根据上一题的方方法:如果是判断多个字符是不是在某一字符串中出现过或者统计多个字符在某个字符串中出现的次数,可以考虑基于数组创建一个简单的哈希表,这样可以用很小的空间消耗来换取时间效率的提升。
2、代码
class Solution
{
public:
Solution()
{
str=' ';
for(int i=0;i<256;++i)
count[i]=0;
}
//Insert one char from stringstream
void Insert(char ch)
{
str+=ch;
count[ch]++;
}
//return the first appearence once char in current stringstream
char FirstAppearingOnce()
{
for(int i=0;i<str.length();++i)
{
if(count[str[i]]==1)
return str[i];
}
return '#';
}
private:
int count[256];
string str;
};