diff --git a/arai60/unique-email-addresses/README.md b/arai60/unique-email-addresses/README.md new file mode 100644 index 0000000..ec50d44 --- /dev/null +++ b/arai60/unique-email-addresses/README.md @@ -0,0 +1,40 @@ +## 考察 +- 初見の問題 +- 方針 + - 文字列操作してHashSetに追加すればよさそう + - C++にはたしかsplitがなかったはずなので、Pythonでやる + - 文字列操作の代わりに正規表現でも出来そう + - ソラでは書ける自信がない(書けるようになっておいた方がいい?) + - 後ほど、調べながらやる + - time: O(nm), space: O(nm) + - n: emails.length, m: max_i(emails[i].length) +- あとは実装 + +## Step1 +- splitとreplaceを使った +- time: O(nm), space: O(nm) + +## Step2 +- まずは正規表現でもやってみる -> `step2_re.py` +- 他の人のPRを検索 + - splitしてからreplaceした方が効率が良い + - Ref. https://github.com/Mike0121/LeetCode/pull/31#discussion_r1642845600 + - 各emailに対する処理は関数化した方がわかりやすいかも + - Ref. https://github.com/SuperHotDogCat/coding-interview/pull/30/files#r1641769186 + - 正規表現について + - Ref. https://github.com/fhiyo/leetcode/pull/17#discussion_r1629618002 + +- 上記を元に各操作を関数化して組み合わせる書き方に修正した +- local_nameとdomain_nameの組み合わせをtupleで表現した + +## Step3 +- 1回目: 2m19s +- 2回目: 2m15s +- 3回目: 2m02s + +## Step4 +- レビューを元に修正 +- privateメソッド相当のものには先頭に _ を付与 +- メソッド名の見直し + - `claen_local_name` -> `_normalize_local_name` + - `remove_after_plus` -> `_remove_plus_and_after` diff --git a/arai60/unique-email-addresses/step1.py b/arai60/unique-email-addresses/step1.py new file mode 100644 index 0000000..755a3c9 --- /dev/null +++ b/arai60/unique-email-addresses/step1.py @@ -0,0 +1,9 @@ +class Solution: + def numUniqueEmails(self, emails: List[str]) -> int: + unique_emails = set() + for email in emails: + local_name, domain_name = email.split('@') + formatted_local_name = local_name.replace('.', '').split('+')[0] + unique_emails.add(formatted_local_name + '@' + domain_name) + + return len(unique_emails) diff --git a/arai60/unique-email-addresses/step2.py b/arai60/unique-email-addresses/step2.py new file mode 100644 index 0000000..01d34cb --- /dev/null +++ b/arai60/unique-email-addresses/step2.py @@ -0,0 +1,20 @@ +class Solution: + def numUniqueEmails(self, emails: List[str]) -> int: + unique_emails = set() + for email in emails: + local_name, domain_name = email.split('@') + unique_emails.add(( + self.clean_local_name(local_name), + domain_name, + )) + + return len(unique_emails) + + def clean_local_name(self, local_name): + return self.remove_all_dots(self.remove_after_plus(local_name)) + + def remove_all_dots(self, text): + return text.replace('.', '') + + def remove_after_plus(self, text): + return text.split('+')[0] diff --git a/arai60/unique-email-addresses/step2_re.py b/arai60/unique-email-addresses/step2_re.py new file mode 100644 index 0000000..668147d --- /dev/null +++ b/arai60/unique-email-addresses/step2_re.py @@ -0,0 +1,10 @@ +class Solution: + def numUniqueEmails(self, emails: List[str]) -> int: + unique_emails = set() + for email in emails: + local_name, domain_name = email.split('@') + local_name = re.sub(r'\+.*', '', local_name) + local_name = re.sub(r'\.', '', local_name) + unique_emails.add(local_name + '@' + domain_name) + + return len(unique_emails) diff --git a/arai60/unique-email-addresses/step3.py b/arai60/unique-email-addresses/step3.py new file mode 100644 index 0000000..c94d89c --- /dev/null +++ b/arai60/unique-email-addresses/step3.py @@ -0,0 +1,19 @@ +class Solution: + def numUniqueEmails(self, emails: List[str]) -> int: + unique_emails = set() + for email in emails: + local_name, domain_name = email.split('@') + unique_emails.add(( + self.clean_local_name(local_name), + domain_name, + )) + return len(unique_emails) + + def clean_local_name(self, local_name): + return self.remove_all_dots(self.remove_after_plus(local_name)) + + def remove_all_dots(self, text): + return text.replace('.', '') + + def remove_after_plus(self, text): + return text.split('+')[0] diff --git a/arai60/unique-email-addresses/step4.py b/arai60/unique-email-addresses/step4.py new file mode 100644 index 0000000..060fbb2 --- /dev/null +++ b/arai60/unique-email-addresses/step4.py @@ -0,0 +1,19 @@ +class Solution: + def numUniqueEmails(self, emails: List[str]) -> int: + unique_emails = set() + for email in emails: + local_name, domain_name = email.split('@') + unique_emails.add(( + self._normalize_local_name(local_name), + domain_name, + )) + return len(unique_emails) + + def _normalize_local_name(self, local_name): + return self._remove_all_dots(self._remove_plus_and_after(local_name)) + + def _remove_all_dots(self, text): + return text.replace('.', '') + + def _remove_plus_and_after(self, text): + return text.split('+')[0]