此为历史版本和 IPFS 入口查阅区,回到作品页
Benjamin
IPFS 指纹 这是什么

作品指纹

[leetcode]929. Unique Email Addresses

Benjamin
·
·
輸入多個符合要求的全小寫信箱地址(確定中間有一個@字元),請判斷傳入參數當中有幾個不重複的信箱地址。

每個傳入的信箱以@區分為信箱名稱和信箱域名。信箱名稱要排除所有dot(.),並且如果遇到加號(+)則到此為止,後面的字母都不用看;信箱域名不受上面規則影響,記錄傳入的完整域名就好。
例如m.y@mail.com和my@mail.com以及my+123@mail.com都是一樣的。

題目:929. Unique Email Addresses
關鍵字:集合(set)


第一版(兩種)

把處理過的地址儲存到去重複的Set之中是非常合理的做法,除此之外也可以先以域名分組加快查詢速度。就像發撲克牌時按照花色整理過之後,要找梅花3只要確認手上的梅花有哪些就好,而不是滿手的牌從頭到尾確認一次,簡單易懂。

那麼,兩種寫法提交出去的結果差多少呢?以下分別是分組後的Set同一個Set的結果:

分組or不分組

第二版,減少字串各字元的比對次數

如連結中看到的程式,總共使用了split('@')切分出名稱和域名的子字串、indexOf("+")確認是否有加號以及所在位置,還有replace(".", "")移除名稱當中的dot,這些功能都是個別獨立,每次都要檢查字串的內容,難免有些字元被重複比對。

怎麼減少比對次數就是這次的主題。說起來用迴圈依序取得字串每個字元,使用switch case判斷要做的事就結束了,但是根據寫法還是會有效能差異。

依序取得字串的每個字元,個人第一個想到的方法會是toCharArray(),但是得到的結果卻不理想,執行時間與調整前一樣是10ms。

推測原因是toCharArray()的使用也是經過一次字串讀取才產生的字元陣列,改為使用charAt直接讀取字串特定位置字元就得到期望的結果了。

使用charAt取得字元,確保整個字串只依序取得一次的結果

其他調整,計算數值的方式與Set, Map的實作方法挑選

題目要求的不重複信箱地址數量,原本的做法是在記錄完所有信箱之後再加總各域名的地址數量,改為在執行過程中加個計數器,判斷當加入Set的新地址確實是尚未記錄的地址則數量+1,效能確實小有提升。

之後在確認Set和Map實作方法的定義和優缺點後更換了方法,效能又再次提升。

最後提交結果

如同之前提到的,實務開發時寫的方式只要足夠好之後細節的效能都只是錦上添花,就像上面用的toCharArray和charAt,修改前其實也領先八成的答題記錄。不過了解每個函式背後的原理還是很重要的,身為程式開發者就是要把寫出更好的程式當目標,而且習慣好的寫法之後就能讓普遍開發的程式變得更好。

所以我現在還能在提交後從自己的程式看出可調整的範圍其實就是一種不成熟的表現,未來希望可以寫出自己挑不出可精進效能的程式。

CC BY-NC-ND 4.0 授权