-
Notifications
You must be signed in to change notification settings - Fork 0
1. Two Sum #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
1. Two Sum #12
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| ## 考察 | ||
| - 過去に何度も解いたことあり | ||
| - 方針は4つ思い浮かぶ | ||
| - 全探索 | ||
| - C(n, 2)パターンを全部調べる | ||
| - 今回はこの方針はスキップ | ||
| - time: O(n^2), space: O(1) | ||
| - ハッシュマップ | ||
| - 追加のメモリを使用する | ||
| - 足し算が可換(答えの順番が関係ない)ので1パスでOK | ||
| - 引き算とかだとおそらく1パスではできない | ||
| - time: O(n), space: O(n) | ||
| - ソートして二分探索 | ||
| - ソートしたら二分探索可能 | ||
| - time: O(n log n), space: O(1) -> space: O(1)は勘違いだった。元のインデックスを保持する必要があるので、正しくはO(n) | ||
| - ソートして2 pointers | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. これ、選択肢になかったです。 |
||
| - メモリO(1)の解法では、最速になると思う | ||
| - ソートがボトルネックになる | ||
| - time: O(n lon n), space: O(1) -> space: O(1)は勘違いだった。元のインデックスを保持する必要があるので、正しくはO(n) | ||
|
|
||
| - ハッシュマップを使った手法を選択 | ||
| - あとは実装 | ||
|
|
||
| ## Step1 | ||
| - ハッシュマップを使った方法を実装 | ||
| - time: O(n), space: O(n) | ||
|
|
||
| ## Step2 | ||
| - 2 pointersの手法でもやってみる | ||
| - ソートするとインデックスが変わるのでそこだけ注意した | ||
| - time: O(n log n), space: O(1) | ||
|
|
||
| ## Step3 | ||
| - ハッシュマップを使った方法で実装 | ||
| - 1回目: 1m02s | ||
| - 2回目: 55s | ||
| - 3回目: 47s | ||
|
|
||
| ## Step4 | ||
| - レビューを元に修正 | ||
| - 変数名を変更 | ||
| - complement -> complement_value | ||
| - Exceptionにメッセージを付与 | ||
| - 呼び出し元に対して親切に | ||
| - enumerateを使ってみた | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| class Solution: | ||
| def twoSum(self, nums: List[int], target: int) -> List[int]: | ||
| n = len(nums) | ||
| num_to_index = {} | ||
| for i in range(n): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for i, num in enumerate(nums):という選択肢もありますね。 |
||
| complement = target - nums[i] | ||
| if complement in num_to_index: | ||
| return [i, num_to_index[complement]] | ||
| num_to_index[nums[i]] = i | ||
|
|
||
| raise Exception() | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. raise Exception('unreachable')のようなメッセージを付けると親切かなと思いました。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. たしかにこちらの方が親切ですね。見直してみます。 |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| class Solution: | ||
| def twoSum(self, nums: List[int], target: int) -> List[int]: | ||
| n = len(nums) | ||
| nums_with_index = [(nums[i], i) for i in range(n)] | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 上に、space: O(1)とありますが、この実装だとO(N)になりませんか。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. O(1)は勘違いでした。この問題の場合、元のインデックスをどこかで保持する必要があるのでO(n)になりますね。。 |
||
| nums_with_index.sort() | ||
|
|
||
| left = 0 | ||
| right = n - 1 | ||
| while left < right: | ||
| num_left, index_left = nums_with_index[left] | ||
| num_right, index_right = nums_with_index[right] | ||
| sum_ = num_left + num_right | ||
| if sum_ == target: | ||
| return [index_left, index_right] | ||
| if sum_ < target: | ||
| left += 1 | ||
| else: | ||
| right -= 1 | ||
|
|
||
| raise Exception() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| class Solution: | ||
| def twoSum(self, nums: List[int], target: int) -> List[int]: | ||
| n = len(nums) | ||
| num_to_index = {} | ||
| for i in range(n): | ||
| complement = target - nums[i] | ||
| if complement in num_to_index: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. やや冗長かもしれませんが、complement_valueのように、indexかvalueかをはっきりさせるとより良いかと思いました。remain_valueとかでも良いかもしれません。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 私も少し気になりました。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ありがとうございます。変数名見直してみます。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 違うことをお伝えして申し訳ないのですが、自分はこのくらいのスコープならやっていることの全体がわかるので
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 個人的にはこの流れで情報を足すなら There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. erutakoさん
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 皆様コメントありがとうございます。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. と書きましたが、正解はなくどれも選択肢のうちの一つだと思うので考える機会を与えてくださりありがとうございます! |
||
| return [i, num_to_index[complement]] | ||
| num_to_index[nums[i]] = i | ||
|
|
||
| raise Exception() | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 認識されているかもしれませんが、他の選択肢もあります
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ありがとうございます。確認しておきます。 |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| class Solution: | ||
| def twoSum(self, nums: List[int], target: int) -> List[int]: | ||
| num_to_index = {} | ||
| for i, num in enumerate(nums): | ||
| complement_value = target - num | ||
| if complement_value in num_to_index: | ||
| return [i, num_to_index[complement_value]] | ||
| num_to_index[num] = i | ||
|
|
||
| raise Exception('unreachable') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a が出てきたときに、x - a = target, a - x = target となるような x があったかを確認すればいいですね。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
たしかに両方見れば大丈夫ですね!勉強になりました。