题目:在字符串中查找第一次出现且只出现一次的字符。
如输入“ababkdcdycghis”,则输出‘k’。
方案一:最直接的方法就是,从字符串的第一个字符开始,顺序扫描和后面的字符进行比较,如果没有发现重复的字符,则说明该字符是第一次出现。由于每个
字符都需要和后面的O(N)字符进行比较, 所以其时间复杂度为O(N^2)。
方案二: 时间复杂度为O(N)。由于题目和字符出现的次数有关,所以我们可以统计每个字符的次数,然后顺序扫面每个字符,第一次出现times=1的字符就是第一次出现且只出现一次的字符。需要两次遍历, 但是两次遍历的时间复杂度为:O(N)。 具体操作是建立一个简单的哈希表,因为哈希表可以确保我们在第二次遍历的时候 在O(1)的时间内得到该字符出现的次数。但是这里借助了 辅助空间,相当于用空间换来了时间的效率。由于是统计字符,所以我们需要一个包含256个字符的辅助数组 ,它的大小是1K,由于这个数组的大小是个常量,所以其空间复杂度为O(1),时间复杂度为O(N)。
具体实现代码如下:
相关题目二:定义一个函数,删除字符串中所有重复出现的字符。例如输入“google”,输出“gole”。
相关题目三:在英语中如果两个单词字母和该字母出现的次数相同,我们称之为互为变位词。例如silent和listen就是变位词。
如输入“ababkdcdycghis”,则输出‘k’。
方案一:最直接的方法就是,从字符串的第一个字符开始,顺序扫描和后面的字符进行比较,如果没有发现重复的字符,则说明该字符是第一次出现。由于每个
字符都需要和后面的O(N)字符进行比较, 所以其时间复杂度为O(N^2)。
方案二: 时间复杂度为O(N)。由于题目和字符出现的次数有关,所以我们可以统计每个字符的次数,然后顺序扫面每个字符,第一次出现times=1的字符就是第一次出现且只出现一次的字符。需要两次遍历, 但是两次遍历的时间复杂度为:O(N)。 具体操作是建立一个简单的哈希表,因为哈希表可以确保我们在第二次遍历的时候 在O(1)的时间内得到该字符出现的次数。但是这里借助了 辅助空间,相当于用空间换来了时间的效率。由于是统计字符,所以我们需要一个包含256个字符的辅助数组 ,它的大小是1K,由于这个数组的大小是个常量,所以其空间复杂度为O(1),时间复杂度为O(N)。
具体实现代码如下:
#include <iostream>
using namespace std;
char FirstNotRepeatingChar(char *strr)
{
if(NULL==strr)
return '\0';
const int tablesize=256;
unsigned int Hashtable[tablesize];//哈希表的大小;
for(unsigned int i=0;i<tablesize;i++)
Hashtable[i]=0;
char *p=strr;
while(*p!='\0')
{
Hashtable[*p]++;
p++;
}
p=strr;
while(*p!='\0')
{
if(Hashtable[*p]==1)
return *p;
p++;
}
return '\0';
}
int main()
{
char str[]="ababkdcdycghis";
char result=FirstNotRepeatingChar(str);
cout<<"The first char is :"<<result<<endl;
system("pause");
return 0;
}
运行结果:
相关题目二:定义一个函数,删除字符串中所有重复出现的字符。例如输入“google”,输出“gole”。
相关题目三:在英语中如果两个单词字母和该字母出现的次数相同,我们称之为互为变位词。例如silent和listen就是变位词。
这些题都是可以用简单的哈希表在O(N)的时间复杂度内解决。