mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-21 19:06:11 +00:00
4.2 KiB
4.2 KiB
練習
知識鞏固
發生雜湊衝突後怎樣查詢
一個雜湊表有 5 個桶,雜湊函式為 $h(x)=x \bmod 5$,衝突時把元素依次放進該桶的串列中。
依次插入 [1, 6, 11, 7]:
- 寫出 0~4 號桶中的內容;
- 查詢 6 時會先進入哪個桶,並依次檢查哪些元素?
- 根據第 1 問寫出的桶內容,後插入的元素是否覆蓋了先插入的元素?結合這種衝突處理方式說明理由。
??? success "參考答案"
1. 因為 $1\bmod5=6\bmod5=11\bmod5=1$,而 $7\bmod5=2$,各桶為:
```text
0: []
1: [1, 6, 11]
2: [7]
3: []
4: []
```
2. 查詢 6 時先進入 1 號桶,再依次比較 1、6,第二次比較時找到目標。
3. 雜湊值相同只表示它們落入同一個桶,並不表示這些元素相等。鏈式位址把衝突元素都儲存在桶內,
查詢時再逐個比較,因此 1、6、11 不會互相覆蓋。
雜湊表擴容後元素去哪兒
一個使用鏈式位址的雜湊表原有 5 個桶,雜湊函式為 $h(x)=x\bmod5$。
鍵 [1, 6, 11] 都在 1 號桶中。
現在把雜湊表擴容為 7 個桶,雜湊函式相應變為 $h(x)=x\bmod7$:
- 分別計算 1、6、11 的新桶號。
- 擴容後哪些桶中有元素?
- 擴容時能否把原來 1 號桶中的串列原樣複製到新的 1 號桶?結合第 1、2 問的結果說明理由。
??? success "參考答案"
1. 新桶號分別為:
- $1\bmod7=1$;
- $6\bmod7=6$;
- $11\bmod7=4$。
2. 1 號桶儲存 1,4 號桶儲存 11,6 號桶儲存 6。三個鍵不再擠在同一個桶中。
3. 不能原樣複製。桶號由“鍵對桶數取餘”得到。桶數從 5 變成 7 後,同一個鍵的新桶號可能改變,
因此必須重新計算每個鍵的位置。若把舊的 1 號桶原樣複製過去,之後按新公式查詢 6 和 11 時,
會分別前往 6 號桶和 4 號桶,從而找不到它們。
刪除 6 後還能找到 11 嗎
一個雜湊表有 5 個位置,索引為 0~4,雜湊函式為 $h(x)=x\bmod5$。
發生衝突時,從雜湊函式算出的索引開始,向右尋找第一個空位。
依次插入 [1, 6, 11]:
- 三個數最終分別放在哪個索引?
- 查詢 11 時,會依次檢查哪些索引?
- 如果刪除 6 時直接把它的位置改成“從未使用的空位”,而查詢遇到空位就停止, 再查詢 11 時會發生什麼?這個查詢結果是否正確?如果有問題,應怎樣避免?
??? success "參考答案"
1. 1 放在索引 1。6 也對映到索引 1,發生衝突後放在索引 2。
11 同樣從索引 1 開始,依次跳過已佔用的索引 1、2,最終放在索引 3。
2. 查詢 11 時依次檢查索引 `1、2、3`,在索引 3 找到它。
3. 如果把索引 2 改成表示“從未使用”的空位,查詢 11 時檢查索引 1 後就會在索引 2 停止,
從而錯誤地認為 11 不存在。刪除時應留下“已刪除”標記:
查詢遇到該標記時繼續檢查下一個索引(越過索引 4 後回到索引 0),而以後的插入仍可重新使用這個位置。
程式設計練習
比較兩個字串的字元組成
給定兩個只含小寫英文字母的字串 s 和 t。
可以任意調整 s 中字元的位置,但不能新增、刪除或替換字元。
請判斷調整後能否得到 t;可以則返回 true,否則返回 false。
請使用雜湊表記錄各字母的出現次數,不對字串中的字元排序。
??? tip "解題提示"
1. 兩個字串長度不同,它們的字元組成一定不同
2. 用雜湊表記錄每種字母的數量;掃描 s 時把對應計數加 1
3. 掃描 t 時把對應計數減 1;所有計數最終都為 0,字元組成才相同
LeetCode{ .rounded-button .exercise-button target="_blank" rel="noopener noreferrer" } 題目解析{ .rounded-button .exercise-button target="_blank" rel="noopener noreferrer" }