-
Notifications
You must be signed in to change notification settings - Fork 0
1. Two Sum #10
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: master
Are you sure you want to change the base?
1. Two Sum #10
Changes from all commits
1821f86
cde8b16
3840457
f850a22
2f4cc1a
a972eb4
3d58967
a285684
cbd2624
5449947
3d4248f
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,121 @@ | ||
## Step1 | ||
### brute force | ||
- nC2通りを全探索して、要件を満たすやつがあったら返す。なかったら[-1, -1]を返す。 | ||
```python | ||
class Solution: | ||
def twoSum(self, nums: List[int], target: int) -> List[int]: | ||
for i in range(len(nums)): | ||
for j in range(i+1, len(nums)): | ||
if nums[i] + nums[j] == target: | ||
return [i, j] | ||
return [-1, -1] | ||
``` | ||
- 時間計算量:O(n^2) 空間計算量O(1) | ||
- データ量が多くなるとTLEになる可能性が高い。 | ||
|
||
```python | ||
class Solution: | ||
def twoSum(self, nums: List[int], target: int) -> List[int]: | ||
number_to_index = {} | ||
|
||
for i in range(len(nums)): | ||
number_to_index[nums[i]] = i | ||
|
||
for number, index in number_to_index.items(): | ||
rest_number = target - number | ||
for i in range(index+1, len(nums)): | ||
if nums[i] == rest_number: | ||
return (index, i) | ||
``` | ||
- Wrong Answer | ||
- 全然ダメ。とりあえずハッシュマップ(数字: インデックス)に全部格納してそこから探そうと考えたが、同じ数字が出てくると反映されないし、いろいろ不都合。 | ||
- Linked List Cycleみたいに、あるかないかを判断してからデータを追加するべきだった。 | ||
|
||
|
||
## Step2 | ||
- ハッシュマップ(数字:インデックス)を用意しておく。そして、所与のリストを頭から検証していって、ハッシュマップに適切なペアがいるかどうかを探す。ペアが見つかったらそれを返す。ない場合は、検証済みのものをマップに格納して、続ける。 | ||
|
||
```python | ||
class Solution: | ||
def twoSum(self, nums: List[int], target: int) -> List[int]: | ||
numbers_to_indeces = {} | ||
|
||
for i in range(len(nums)): | ||
rest = target - nums[i] | ||
if rest in numbers_to_indeces: | ||
return [i, numbers_to_indeces[rest]] | ||
numbers_to_indeces[nums[i]] = i | ||
|
||
return [-1, -1] | ||
``` | ||
- 関数の型アノテーションを見る。-> List[int]なので、Noneとかを投げさせない。 | ||
- 時間計算量:O(n) 空間計算量:O(n) | ||
- `[3, 3, 2] target=5`を見る。答えとして`[2, 1](not [2, 0])`が返されるだろう。(今回は答えが一意に定まるが……) | ||
|
||
### みつからなければ例外を投げる | ||
```python | ||
class Solution: | ||
def twoSum(self, nums: List[int], target: int) -> List[int]: | ||
|
||
number_to_index = {} | ||
|
||
for index, number in enumerate(nums): | ||
rest_number = target - number | ||
if rest_number in number_to_index: | ||
return [index, number_to_index[rest_number]] | ||
number_to_index[number] = index | ||
|
||
raise Exception('not found') | ||
``` | ||
- 時間計算量:O(n) 空間計算量:O(n) | ||
|
||
|
||
- built-in exceptionsに関する公式ドキュメントの確認。 | ||
https://docs.python.org/ja/3.13/library/exceptions.html#bltin-exceptions | ||
- 一番近いのはValueError。他の方のコードなどをみる限り、やはりそうらしい。 | ||
- raiseはエラーを発生させてるだけだし、実務上では関数呼び出しがtryの中で行われるのかな? | ||
- しばらく経って改めて眺めてみると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. 私見ですが載せておきます t0hsumi/leetcode#11 (comment) 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. ありがとうございます。 L76は私が例外に対して無知すぎたためかなり初歩的な話なのですが、 try:
solution.twoSum(nums, target)
except ValueError as e:
print(e) などと書かれるのだろう、という話をしています |
||
|
||
## Step 3 | ||
```python | ||
class Solution: | ||
def twoSum(self, nums: List[int], target: int) -> List[int]: | ||
numbers_to_indeces = {} | ||
|
||
for i in range(len(nums)): | ||
complement = target - nums[i] | ||
if complement in numbers_to_indeces: | ||
return [i, numbers_to_indeces[complement]] | ||
numbers_to_indeces[nums[i]] = i | ||
|
||
raise ValueError('no solution found') | ||
``` | ||
```python | ||
class Solution: | ||
def twoSum(self, nums: List[int], target: int) -> List[int]: | ||
numbers_to_indexes = {} | ||
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. 個人的には num_to_indices が良いと思います。 number という英単語については、入力の変数名が nums と number を省略して複数形にした形のため、省略してしまってよいと思います。また、あくまで個人的な好みになりますが、複数の値が含まれる変数の変数名は、複数の値が含まれることを明示するため、複数形で終えるようにしています。 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. @nodchip 個人的な好みと強調されているところすみません、こちら、num一つに対しindex一つの1対1のmapだと思うのですが、それでも複数形にするということでしょうか?? 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. @nodchip なるほどです!ありがとうございます! 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. ありがとうございます。揚げ足取りになって試合申し訳ないのですが、 data は複数形です。数的には大勢に影響はないため、無視していただいて大丈夫だと思います。 |
||
for i, num in enumerate(nums): | ||
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. 好みのレベルですが、今回の問題に限ってはindexそのものを扱っているのでiではなく |
||
complement = target - num | ||
if complement in numbers_to_indexes: | ||
return [i, numbers_to_indexes[complement]] | ||
numbers_to_indexes[num] = i | ||
|
||
raise ValueError('pair not found') | ||
``` | ||
# 例外について | ||
- 全ての親であるBaseExceptionクラスの継承クラスにはException、KeyBoardInterruptなどのがあり、大体のエラーはExceptionの継承クラスといえる。ZeroDivisionErrorやOverFlowErrorなどの計算に関する例外はArithmeticErrorというExceptionのサブクラスの、サブクラス(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. その都度調べたくなることが大事と思います。 |
||
``` | ||
Exception | ||
ArithmeticError | ||
ZeroDivisinError | ||
OverFlowError | ||
ValueError | ||
LookupError | ||
IndexError | ||
... | ||
``` | ||
- エラーメッセージはデフォルトで追加されているものもある。 | ||
- ZeroDivisionError: division by zero | ||
- IndexError: index out of range etc | ||
- エラーの仕組みは詳しく知らなかったため、勉強になった。 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
```python | ||
class Solution: | ||
def twoSum(self, nums: List[int], target: int) -> List[int]: | ||
for i in range(len(nums)): | ||
for j in range(i + 1, len(nums)): | ||
if nums[i] + nums[j] == target: | ||
return [i, j] | ||
|
||
raise ValueError('no appropriate pair') | ||
``` | ||
|
||
```python | ||
class Solution: | ||
def twoSum(self, nums: List[int], target: int) -> List[int]: | ||
number_to_indices = {} | ||
|
||
for i in range(len(nums)): | ||
complement = target - nums[i] | ||
if complement in number_to_indices: | ||
return [i, number_to_indices[complement]] | ||
number_to_indices[nums[i]] = i | ||
|
||
raise ValueError('no appropriate pair') | ||
``` |
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.
時間計算量から、おおよその実行時間を見積もることができます。詳しくは過去のレビューコメントをご参照ください。
https://discord.com/channels/1084280443945353267/1307605446538039337/1336992875577081917