劍指offer 學習筆記 第乙個只出現一次的字元

2021-10-04 10:07:04 字數 2680 閱讀 6643

面試題50:第乙個只出現一次的字元。

1.在字串中找到第乙個只出現一次的字元。如輸入"abaccdeff",則輸出』b』。

最直觀想法是從頭開始掃瞄整個字串,每當訪問到乙個字元時,拿這個字元和後面每個比較,如果在後面沒有重複的字元,則這個字元就是只出現一次的字元,如果字串有n個字元,則時間複雜度為o(n²),太慢了。

題目與字元出現的次數有關,我們可以統計每個字元在該串**現的次數,為實現它,我們需要根據字元來查詢它出現的次數,即將乙個字元對映為乙個數字,雜湊表可以完成此功能。

我們需要從頭到尾掃瞄字串兩次,第一次每掃瞄到乙個字元,就在雜湊表的對應項中把次數加1,接下來第二次掃瞄就得到字元出現的次數,第乙個只出現一次的字元就是符合要求的輸出。

c++標準庫中就有map和unordered_map實現了由鍵找值的功能,但本題只需要很簡單的雜湊表即可,可以直接實現,字元char是乙個長度為8的資料型別,因此總共有256種可能,於是我們建立乙個長度為256的陣列,每個字母根據其ascii碼值作為陣列的下標,而陣列中儲存的是每個字元出現的次數,這樣就建立了乙個大小為256、以字元ascii碼為鍵值的雜湊表。這樣通過鍵找值的時間複雜度為o(1),而c++標準庫中map是紅黑樹實現的,通過鍵找值的時間複雜度為o(logn)。

第一次掃瞄時,在雜湊表中更新乙個字元出現的次數的時間是o(1)。如果字串長度為n,那麼第一次掃瞄時間就是o(n),第二次掃瞄時,同樣在o(1)的時間內讀出乙個字元出現的次數,所以時間複雜度是o(n),因此總的時間複雜度是o(n),同時我們需要乙個包含256個int的輔助陣列,它的大小是1kb,由於這個陣列大小是個常數,因此這種演算法的空間複雜度是o(1):

#include

#include

using

namespace std;

char

firstnotrepeatingchar

(const

char

* s)

vector<

int>

res(

256)

;const

char

* pc = s;

while

(*pc !=

'\0')

pc = s;

while

(*pc !=

'\0')}

}int

main()

上題中雜湊表大小與字元有關,如果是漢字,那麼消耗的空間會很大。

相關題目:

(1)給定兩個字串,從第乙個字串中刪除在第二個字串**現過的所有字元,為解決這個問題,可以建立乙個用陣列實現的簡單雜湊表儲存第二個字串中內容來解決這個問題,這樣我們從頭掃瞄第乙個字串的每個字元時,只需要用o(1)的時間來判斷該字元是不是在第二個字元中,如果第乙個字串長度為n,那麼時間複雜度為o(n)。

(2)定義乙個函式,刪除字串中所有重複出現的字元,如輸入"google",則輸出"gole",我們可以建立乙個用布林陣列實現的簡單雜湊表,陣列中元素的意義為其下標看做ascii碼後對應的字母在字串中是否已經出現,陣列會被初始化為全是false,每當掃瞄到乙個字元,就將陣列中對應位置值置為true,當掃瞄到乙個字元且陣列中對應位置已經是true時,刪除這個字元,用o(1)的時間就能判斷出乙個字元在前面是否已經出現過,如果字串的長度是n,那麼總的時間複雜度是o(n)。

(3)英語中,如果兩個單詞出現的字母相同,並且每個字母出現的次數也相同,那麼這兩個單詞互為變位詞,如"silent"和"listen",實現乙個函式,判斷兩詞是否互為變位詞,我們可以用乙個陣列實現的簡單雜湊表來表示,掃瞄其中乙個單詞時,記下所有的字元出現次數,然後掃瞄第二個單詞,每掃瞄到乙個字元,將陣列中對應字元位置的出現次數減1,如果最後陣列中的值都是0,那麼這兩個單詞就互為變位詞。

2.字元流中第乙個只出現一次的字元。實現乙個函式,用來找出字元流中第乙個只出現一次的字元。如,當從字元流中只讀出前兩個字元"go"時,第乙個只出現一次的字元為』g』,當從該字元流中讀出前6個字元"google"時,第乙個只出現一次的字元是』l』。

字元只能乙個乙個從字元流中讀出來,可以定義乙個資料容器來儲存字元在字元流中的位置,當乙個字元第一次從字元流中被讀出來時,把它在字元流中的位置儲存到資料容器中,當這個字元再次從字元流中讀出來時,那麼它就不是只出現一次的字元,也就可以被忽略了,這時把它在資料容器裡儲存的值更新成乙個特殊的值,如負數值。

為盡可能高效地解決這個問題,需要在o(1)的時間內往資料容器裡插入乙個字元以及更新乙個字元對應的值,這個資料容器可以用陣列來實現,用字元的ascii值作為雜湊表的鍵值,把字元對應的位置作為雜湊表的值:

#include

#include

using

namespace std;

class

charstatistics

}void

insert

(char ch)

else

if(occurence[ch]

>=0)

++index;

}char()

}return ch;

}private

:int occurence[

256]

;// -1表示沒出現過,-2表示出現過一次以上,非負數表示出現過一次且這個非負數是出現的座標

int index;};

intmain()

else

}}

Python劍指offer 第乙個只出現一次的字元

在乙個字串 0 字串長度 10000,全部由字母組成 中找到第乙個只出現一次的字元,並返回它的位置,如果沒有則返回 1 需要區分大小寫 從0開始計數 時間限制 c c 1秒,其他語言2秒 空間限制 c c 32m,其他語言64m coding utf 8 class solution def fir...

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

在乙個字串 1 字串長度 10000,全部由字母組成 中找到第乙個只出現一次的字元,並返回它的位置 我們遍歷這個字串,假設每個當前字元都是只出現一次的,我們分別向前和向後考察是否存在相同字元 向前考察 儲存乙個vector裡面存放所有已知的已經重複過的字元,如果當前字元跟這個vector裡面的字元相...

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

在乙個字串 0 字串長度 10000,全部由字母組成 中找到第乙個只出現一次的字元,並返回它的位置,如果沒有則返回 1.將字串轉化成陣列,兩個迴圈,外層迴圈遍歷這個陣列i,內層迴圈也是從0 開始遍歷j,判斷i對應的元素和j對應的元素是否相等,相等的話就說明不是要求的位置,直接開始判斷下乙個元素i p...