ゼロから始めるLeetCode Day94 「929. Unique Email Addresses」

概要

海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

どうやら多くのエンジニアはその対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイトであり、海外のテックカンパニーでのキャリアを積みたい方にとっては避けては通れない道である。

と、仰々しく書いてみましたが、私は今のところそういった面接を受ける予定はありません。

ただ、ITエンジニアとして人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

Leetcode

Python3で解いています。

ゼロから始めるLeetCode 目次

前回
ゼロから始めるLeetCode Day93 「49. Group Anagrams」

次回
まだ

Twitterやってます。

問題

929. Unique Email Addresses
難易度はEasy。
コーディング面接対策のために解きたいLeetCode 60問からの抜粋です。

問題としては、すべての電子メールは、@記号で区切られたローカル名とドメイン名で構成されています。
例えば、alice@leetcode.com では、alice がローカル名で、leetcode.com がドメイン名です。
小文字の他に、これらの電子メールには ‘.‘や’+‘が含まれている場合があります。
メールアドレスのローカル名の一部の文字の間にピリオド(’.’)を追加すると、ローカル名のドットがない同じアドレスに送信されたメールが転送されます。 例えば、「alice.z@leetcode.com」と「alicez@leetcode.com」は同じメールアドレスに転送されます。 (この規則はドメイン名には適用されませんのでご注意ください)。
ローカル名にプラス(’+’)を追加した場合、最初のプラス記号以降はすべて無視されます。これにより、特定のメールをフィルタリングすることができます。例えば、m.y+name@email.com は my@email.com に転送されます。 (繰り返しになりますが、このルールはドメイン名には適用されません)。
これらのルールを同時に適用することも可能です。
仮に電子メールのリストが与えられた場合、リスト内の各アドレスに1つの電子メールを送信します。 実際にメールを受信するアドレスはいくつあるでしょうか?

Example 1:

Input: [“test.email+alex@leetcode.com”,“test.e.mail+bob.cathy@leetcode.com”,“testemail+david@lee.tcode.com”]
Output: 2
Explanation: "testemail@leetcode.com" and "testemail@lee.tcode.com" actually receive mails

解法

class Solution:
    def numUniqueEmails(self, emails: List[str]) -> int:
        fixed_email = set()
        for lists in emails:
            local,domain = lists.split("@")
            local = local.split("+")[0].replace(".","")
            fixed_email.add(local + "@" + domain)
        return len(fixed_email)
# Runtime: 52 ms, faster than 77.31% of Python3 online submissions for Unique Email Addresses.
# Memory Usage: 14.2 MB, less than 5.16% of Python3 online submissions for Unique Email Addresses.

実装の面で苦労する、というよりは問題を噛み砕いて考える方が難しいかもしれませんね。
集合を管理する場合、Pythonではset()を使うと和集合や積集合などを簡単に取り扱うことができるのでおすすめです。

流れとしてはfor文で全てのリストを網羅するというのが大前提にあり、その中でどういった処理を行うかがこの問題の核となるでしょう。
僕はsplit()を使ってlocal部分とdomain部分に分け、問題文で書かれているように最初の+以外は無視して良いので最初の+で分割し、全ての.を無くすことで判別を行いました。
最終的に集合の長さを返せばきちんと実際にメールを受信するアドレスの数、となるといった仕組みです。

この問題は集合の知識が必要かと最初は思うかもしれませんが、実質的には数え上げに近く、Hashmap的な問題だとリンク先では紹介されていました。

初見だと面食らうかもしれないので実際に解くことをお勧めします。

では今回はここまで。お疲れ様でした。

コメント

このブログの人気の投稿

Braveブラウザ(iPhone,iPad)にオフラインでもYouTubeの動画が視聴可能なPlaylist機能が追加されていたので使い方をまとめてみた。

自作のChrome Extensionをインポートした時に "Invalid value for 'content_scripts[0].matches[0]': Empty path."というエラーが出たので解決した

Braveブラウザの同期機能をiPhoneで設定した話。