從今天開始要刷這個網站了,時間再緊,也要堅持下去!
題目:
Implement an algorithm to determine if a string has all unique characters. What if you can not use additional data structures?
翻譯:
實現一個算法來判斷一個字符串中是否沒有重復的字符,只能使用基本的數據結構。
思路:
我們這裡假設字符串為26個小寫字母(當然我們可以擴充到整個ASCII碼表,下面會說)。思路很多啦!可以使用桶排序的思想,分成26個桶,如果有桶中元素個數大於1,則出現重復,但實際上我們沒必要對字符串進行排序,直接判斷即可,因此我們可以使用哈希表,將26個小寫字母映射到一個哈希表中,但因為只能使用基本的數據結構,因此我們可以使用哈希的思想,將26個小寫字母映射到一個數組中(其實也還是哈希表啦,只是使最簡單的直接尋址表)。
我們開辟一個大小為26的int數組,記錄26個小寫字母在字符串中出現的次數,初始為0,出現一次對應位置變為1,再出現一次的話,就說明有重復了,直接返回false即可。
這樣子只需遍歷一次字符串,的時間復雜度為O(n),需要額外的26個int輔助空間。
實現代碼:
/* 判斷是否有重復字符 */ bool unqString(string s) { unsigned int i; unsigned int len = s.length(); unsigned int arr[MAX]; for(i=0;i由於實際上arr數字中的每個元素只可能為0或1(一旦為1時,判斷再次出現,就直接返回false),因此我們可以用bool數組來代替unsigned int數組,這樣可以節省內存(32位的系統中,unsigned int占4個字節,而bool占一個字節)。
完整代碼如下:
/********************************************************** 題目描述: 判斷一個字符串中是否沒有重復的字符,只能使用基本的數據結構 Date:2014-03-15 **********************************************************/ #define MAX 26 #include#include using namespace std; /* 判斷是否有重復字符 */ bool unqString(string s) { unsigned int i; unsigned int len = s.length(); unsigned int arr[MAX]; for(i=0;i yes< no< yes< no<
測試結果如下:
s1->yes s2->no
如果我們將字符串中字符的范圍擴大到整個ASCII編碼表,需要注意:ASCII編碼表的0-127是標准編碼,而128-255為擴展編碼(一般情況下是用不到的,編譯器的實現對該部分的編碼也沒有任何統一的標准),如果保存為char類型,就變為負值了,即變成了-128—-1。因此,在寫程序的時候,對0-127這部分字符可以直接轉化為對應的整數來作為其在arr數組中的位置,而對與128-255這部分字符,則要將其轉化為整數後再加256,將得到的數作為其在arr數組中的位置。
另外,還有人通過位運算來解決該問題,挺新穎的思路,不過空間代價與用bool數組時一樣的,而且思想也大同小異。這裡不再給出。