【劍指offer】第一個只出現一次的字元

蘭亭風雨發表於2014-05-27

轉載請註明出處:http://blog.csdn.net/ns_code/article/details/27106997

題目描述:

在一個字串(1<=字串長度<=10000,全部由大寫字母組成)中找到第一個只出現一次的字元。

輸入:

輸入有多組資料
每一組輸入一個字串。

輸出:

輸出第一個只出現一次的字元下標,沒有隻出現一次的字元則輸出-1。

樣例輸入:
ABACCDEFF
AA
樣例輸出:
1
-1

    處理字串中重複或者次數出現等問題,最常用的就是雜湊表,用字串中的字元作為key,字元出現次數作為value,假定只有ASCII碼範圍內的字元,則可以開闢一個256大小的int陣列,將每個字元(key)對映到該陣列的對應位置上,計算每次出現的次數即可,遍歷一次字串,計算每個字元出現的次數,儲存在int陣列的對應位置上,第二次遍歷字串,若第一次出現某個字元對對應到的雜湊表的對應位置處的元素為1,則該字元便是第一個只出現一次的字元,如果我們是遍歷雜湊表(int陣列),則找到的雜湊表中的第一個元素為1的位置對應的字元為字串中第一個最小的只出現一次的字元。時間複雜度為O(n),需要額外的256個int空間來輔助,可以看做空間複雜度為O(1)。

    另外,如果要省空間,我們可以bitmap演算法,用兩個位來表示對應字元出現的次數,出現0次,則為00,出現一次則為01,出現2次及以上,都維持在10即可。

    另外,有一點需要注意,char的範圍在-128-127,unsigned char的範圍才是在0-255,因此ASCII值在128-255之間的字元,如果儲存為了char型,其轉化為int值的範圍是在-128--1之間,這點在下面的程式碼中有體現。

    下面給出用簡單雜湊表AC的程式碼(根據題目要求和測試要求分別寫了兩個函式):

#include<stdio.h>
#include<string.h>

/*
返回第一個出現一次的字元
*/
char FirstOnceChar(char *str)
{
	if(str == NULL)
		return '\0';

	int hashtable[256];
	memset(hashtable,0,sizeof(hashtable));
	char *pCur = str;
	while(*pCur != '\0')
	{
		if(*pCur>=0)
			hashtable[*(pCur++)]++;
		else
			hashtable[*(pCur++)+256]++;
	}

	while(*str != '\0')
	{
		int index;
		if(*str>=0)
			index = *str;
		else
			index = *str+256;

		if(hashtable[index] == 1)
			return *str;
		else
			str++;
	}
	return '\0';
}

/*
返回第一個出現一次的字元的下標
*/
int IndexOfFirstOnceChar(char *str)
{
	if(str == NULL)
		return -1;

	int len = strlen(str);
	int hashtable[256];
	memset(hashtable,0,sizeof(hashtable));
	int i;
	for(i=0;i<len;i++)
	{
		if(str[i]>=0)
			hashtable[str[i]]++;
		else
			hashtable[str[i]+256]++;
	}

	for(i=0;i<len;i++)
	{
		int index;
		if(str[i]>=0)
			index = str[i];
		else
			index = str[i]+256;

		if(hashtable[index] == 1)
			return i;
	}
	return -1;
}

int main()
{
	char str[10010];
	while(gets(str) != NULL)
		printf("%d\n",IndexOfFirstOnceChar(str));
	return 0;
}
/**************************************************************

    Problem: 1283
    User: mmc_maodun
    Language: C
    Result: Accepted
    Time:10 ms
    Memory:912 kb
****************************************************************/


相關文章