Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions 49/memo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# 49. Group Anagrams

- [リンク](https://leetcode.com/problems/group-anagrams/description/)
- 愚直にsol1を書いたが計算量はO(nllog(l))
- histogramを用いる解法
- https://github.com/ichika0615/arai60/pull/11/changes#diff-fa3129c54f54ceaf0d237e449d3491c5eb44eaa4660ae11dec87df81d245cb25
- リストはmutableでhashableではないのでtupleに変換する必要がある
- 計算量はO(nl)
- 入力がアルファベット小文字以外のときには例外処理で対応
- 実行時間はsol1の方が速い
- pythonのsortedが高速でloglが定数倍より速い?
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Native code の部分だというだけで感覚10-20倍程度速いです。

下につけたのは適当に拾ってきたソートの速度の比較ですが、ネイティブコードにすると10-20倍くらいは簡単に変わるんですね。
C 言語と Python は50-100倍くらい違い、ただしネイティブコードでもガーベージコレクションなど Python Object の操作をしないといけないので、C 言語並までにはならないだろうくらいの推測です。
https://discord.com/channels/1084280443945353267/1367399154200088626/1372840818397810701

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なるほど、そう考えると色々な組み込み関数は知っておくと良さそうです。(基数ソートをRadix sortというの知らなかったです。これが一番速いんですね)

10 changes: 10 additions & 0 deletions 49/sol1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from collections import defaultdict


class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
anagram_sets = defaultdict(list)
for orig_str in strs:
sorted_str = sorted(orig_str)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

私は "".join まで上の行でしてしまうかもしれません。まあ、どちらでもいいです。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorted_key = "".join(sorted(orig_str))
anagram_sets[sorted_key].append(orig_str)

この方が見やすいですね

anagram_sets["".join(sorted_str)].append(orig_str)
return list(anagram_sets.values())
22 changes: 22 additions & 0 deletions 49/sol2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from collections import defaultdict

NUM_POSSIBLE_CHARS = 26
START_CHAR = "a"
ORD_START_CHAR = ord(START_CHAR)


class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
def str_to_frequency(input_str):
frequency = [0] * NUM_POSSIBLE_CHARS
for input_char in input_str:
ord_input_char_rel = ord(input_char) - ORD_START_CHAR
if ord_input_char_rel >= NUM_POSSIBLE_CHARS:
raise ValueError
frequency[ord_input_char_rel] += 1
return tuple(frequency)

frequency_to_strs = defaultdict(list)
for input_str in strs:
frequency_to_strs[str_to_frequency(input_str)].append(input_str)
return list(frequency_to_strs.values())