標籤:style class blog code http ext
Google 2006年的一道筆試題,難度係數低
題目描寫敘述:
在一個字串中找到第一個僅僅出現一次的字元。如輸入abaccdeff,則輸出b。
邏輯分析:
1、簡單粗暴O(n^2),一個顯而易見的想法是像冒泡排序一樣,採用兩個迴圈,內層迴圈對外層判定元素arr[i]進行輪詢,當發現arr[i] == arr[j]時,本次迴圈終止,顯然,時間複雜度O(n^2),不使用額外空間。
#include <stdio.h>#include <stdlib.h>#include <string.h>void findSingle(char *arr, int len){ int i,j; for(i=0;i<len;i++) { for(j=i+1;j<len;j++) { if(arr[i] == arr[j]) { break; } if(j == len - 1) { printf("%c",arr[i]); return ; } } }}int main(){ char str[] = "abaccdeff"; findSingle(str,strlen(str)); return 0;}
2、上述做法儘管可行,只是O(n^2)的時間複雜度顯然不理想,我們須要換個思路,考慮一下怎樣將時間複雜度降為O(n),必要時能夠用空間來換。直觀上,我們僅僅想遍曆一次字串(即單層迴圈),那麼必定就須要將某些資訊記錄下來,這裡記錄的當然就是每一個字元出現的次數。對於字串來講,一般採用雜湊表,然後對雜湊表進行查詢就可以。本題針對字串為小寫字母形式,所以能夠簡單的採用int hashtable[26] = {0};來做儲存。
void findSingle(char *arr, int len){ int hashtable[26] = {0}; int i; for(i=0;i<len;i++) hashtable[arr[i]-'a']++; for(i=0;i<len;i++) { if(hashtable[arr[i]-'a'] == 1) { printf("%c\n",arr[i]); break; } } if(i >= len) { printf("無滿足字元\n"); }}
O(n)的時間複雜度,O(1)的空間複雜度。
3、擴充:一般來講,對於字串的問題,通常藉助ASCII和雜湊解決,上述代碼2類比小型雜湊,僅僅對26個小寫字母做了處理,擴充則使用2^8=256長度雜湊。這裡,不再小題大做。