題目一:字符串中第一個只出現一次的字符
【在一個字符串(0<=字符串長度<=10000,全部由字母組成)中找到第一個只出現一次的字符,並返回它的位置, 如果沒有則返回 -1(需要區分大小寫)】
方法一:自建簡易hashTable
1、分析
(1)、一種思路是將每個字符分別與後面的字符進行比較,若沒有與它相同的則就是該字符。這種方法的時間複雜度是 。可以採用令一種方法,使用空間換時間。創建一個數組用來存放每個字符出現的次數,同時將字符串與該數組之間建立映射關係。在統計完每個字符出現的次數之後,再遍歷該字符串的時就可以得到每個字符出現的次數。這種方法需要兩次遍歷該字符串,時間複雜度爲 。
(2)、在統計每個字符出現次數的時候,可以以字符所對應的 ASCll 碼爲統計數組中元素的下標,數組中則存放該 ASCll 碼所對應字符出現的次數。因爲 char 字符佔一個字節,即8位二進制,其能表示的大小是 個字符,所以可以用一個長度爲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;
};