LeetCode | 你不得不瞭解的雜湊演算法 !
⒈ 雜湊是什麼 ?
問大家一個問題 。如果手機上儲存了 1000 個聯絡人 ,現在要你給小詹打個電話 ,跟他說 ,他老婆喊他回家吃飯 。你會怎麼做 ?
當然是按姓名搜尋呀 !(假裝你有小詹電話號碼~)言歸正傳 ,那你能想到這和雜湊表有異曲同工之妙嘛 ?
雜湊表簡單說可以理解成一個對映關係 ,類似 python 語法中字典的鍵值對 。根據鍵(Key)而直接訪問在記憶體儲存位置的資料結構。
將任意長度的二進位制值串對映為固定長度的二進位制值串 ,這個對映的規則就是雜湊演算法 。原始資料對映得到的二進位制值串就是雜湊值 。
回到通訊錄的例子 ,是不是可以類比 ? 電話號碼是原始資料 ,根據雜湊演算法(這就是你自定義的規則)儲存為通訊錄備註 。嚴格來講二者是有區別的 ,只是為了便於理解 ,若舉例不當 ,槓精讀者輕噴 。
一個優秀的雜湊演算法主要有以下幾點特徵 :
● 單方向推導,不能從雜湊值反向推匯出原始資料 ,或者說很困難 。
● 對輸入敏感,原始資料的微小變化會導致雜湊值的大差異 。
● 雜湊衝突小,不同原始資料得到相同雜湊值的概率小 。其實最好是避免 ,但是諸如 MD5 這種也難以徹底避免 ,所以只說儘可能小 。
● 執行效率高,即使是較長的文字 ,也能快速計算出雜湊值 。
⒉ 雜湊演算法有何用 ?
一般而言 ,演算法或產品的使用往往取決於特徵 。所以根據上文的特徵不難想到一些應用如下 。
● 安全加密
因為優秀的雜湊演算法具有單方向推導 和雜湊衝突小 兩個特徵 ,這就決定了用來進行安全加密具有很好的應用 。
相信你一定聽過 MD5(MD5 Message-Digest Algorithm ) 和 SHA(Secure Hash Algorithm)吧 ,這就是兩個常用於安全加密的雜湊演算法 。
● 資料結構
其實還有很多應用與安全加密類似 ,比如資料校驗之類的 ,都是利用單向性和衝突小特性 ,就不贅述了 。
其實雜湊演算法在資料結構中用於查詢是一個非常不錯的方法 ,可以快速定位查詢到想要查詢的資料資訊 。這一用法在刷 LeetCode 題的時候遇到的非常多 !
⒊ 雜湊演算法刷題
● K數之和
Leetcode第一題就是兩數之和 ,後邊又有三數之和 、四數之和 ,其實 K 數之和原理類似 。
以兩數之和為例 ,除了簡單暴力的遍歷方法 ,雜湊演算法能夠極大的提高解題效率 !具體參照第一題推文的第二種解法 :
ofollow,noindex" target="_blank">LeetCode | No.001 兩數之和
● 模式匹配
模式匹配問題比較經典 。最簡單的舉例 :數字串「 1 2 1 2 」應該對應英文「 one two one two 」。
現在如果給定一個模式(數字串)和一個輸入(英文),要你寫程式碼實現判斷是否模式匹配 ,你該怎麼做呢 ? 這一題來個有獎互動 !
其實這就可以考慮使用雜湊演算法實現了 ,python 中的字典有個鍵值對 ,其實有些類似 ,這裡小詹給出思路 ,不分享程式碼 。按照思路用 python 寫出可行程式碼的同學歡迎在留言區回覆 ,將在前 3 個親測有效的程式碼中選取一個最優的送上實體書一本(下次送書活動預留一個名額)歡迎動腦 ,中獎概率三分之一
思路如下 :
● 首先對輸入的英文串分割 ,可以用 input.split(' ') 方法 。
● 建立雜湊表儲存資料 ,這裡友情提醒下可以建立多個喲 。
● 從給定模式逐一迴圈判斷 。單次判斷邏輯如下列出 。
● 首先判斷當前位置的模式(pattern)是否初次出現 ,如果不是第一次出現 ,則說明有一個雜湊值與之相對應 ,判斷 input 對應位置是否與該雜湊值一致 ,如果不一致則直接返回 false ,肯定不匹配 。
● 如果當前模式是第一次出現 ,先不急著直接加入雜湊表 ,還需要判斷對應位置的 input 英文單詞是否是其他模式的雜湊值 ,如果是說明之前已經和別的模式匹配了 ,不能反覆匹配 ,返回 false 。
● 如果當前位置的模式是第一次出現且對應的 input 也沒有和別的模式匹配過 ,則二者作為一個鍵值對存入雜湊表 。
● 如果直到迴圈結束沒有返回 false 說明完全匹配 ,返回 true 。
原文釋出時間為:2018-11-29