这个题目可以看做是一类题型。就是从一个数组中找出不重复的第一个或是全部的数,或是在一个字符串当中找。另外还可以做成大数据的情况,例如,给你一亿或是几亿个数,32位的int类型,让你找出所有的不重复的数。
基本思路有几个,第一个推荐的方法是位图BitMap,哈希表Hashtable。第二个方法是异或法,此方法在剑指offer中有介绍。下面详细来分析如何解决此类问题。
HashTable法
对于查找第一个只出现一次的字符,我们可以用一个数据容器来存放每一个字符出现的次数,在这个容器中,可以根据字符来查找它出现的次数,也就是说把字符映射成一个数字。
我们可以定义一个哈希表,他的键值(Key)是字符,而值(Value)是该字符出现的次数。同时需要扫描字符数组两次。第一次用于统计所有字符出现的次数。第二遍时,可以输出第一个只出现一次的字符,也可以设置输出所有只出现一次的字符。
下面关键一步是定义Hashtable。因为是字符,所以只有256种情况,不考虑中文字符。那么我们就建一个256大小的数组,用字符的ASCII码值作为下标,即该字符的ASCII码值就是其在数组中的位置。好的,代码如下:
char FindNotRepeatedChar(char *string)
{
if (string == NULL)
return '\0';
const int Tablesize = 256;
unsigned int HashTable[Tablesize] = {0};
char* pHash = string;
while ((*pHash) != '\0')
{
HashTable[*pHash]++;
pHash++;
}
pHash = string;
while (*pHash != '\0')
{
if (HashTable[*pHash] == 1)
<span style="white-space:pre"> </span>{<span style="white-space:pre"> </span>
return *pHash;
<span style="white-space:pre"> </span>break;<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>}
pHash++;
}
return '\0';
}
BitMap
代码参考:
# include<stdio.h>
# include<string.h>
const int N = 26;
int bit_map[N];
void findNoRepeat(char *src)
{
int pos;
char *str = src;
int i ,len = strlen(src);
//统计
for(i = 0 ; i < len ;i ++)
bit_map[str[i]-'a'] ++;
//从字符串开始遍历 其bit_map==1 那么就是结果
for(i = 0 ; i < len ; i ++)
{
if(bit_map[str[i]-'a'] == 1)
{
printf("%c",str[i]);
return ;
}
}
}
int main()
{
char *src = "abaccdeff";
findNoRepeat(src);
printf("\n");
return 0;
}
题目可以是: 在2.5亿个整数中找出不重复的整数,内存不足以容纳这2.5亿个整数。
方案1:采用2-Bitmap(每个数分配2bit,00表示不存在,01表示出现一次,10表示多次,11无意义)进行,共需内存2^32*2bit=1GB内存,还可以接受。然后扫描这2.5亿个整数,查看Bitmap中相对应位,如果是00变01,01变10,10保持不变。扫描遍历完事后,查看bitmap,把对应位是01的整数输出即可。
方案2:也可采用上题类似的方法,进行划分小文件的方法。然后在小文件中找出不重复的整数,并排序。然后再进行归并,注意去除重复的元素。