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
121 changes: 121 additions & 0 deletions arai60_11.md
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になる可能性が高い。
Copy link

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


```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はやばい。広すぎる。

Choose a reason for hiding this comment

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

私見ですが載せておきます t0hsumi/leetcode#11 (comment)
L76の話、これどういう意味か聞いてもいいですか?

Copy link
Owner Author

Choose a reason for hiding this comment

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

ありがとうございます。

L76は私が例外に対して無知すぎたためかなり初歩的な話なのですが、
raise で例外を発生させる部分だけを今は実装していて、実務ではこれが部品として使われる際は

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 = {}

Choose a reason for hiding this comment

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

number_to_indexの方がいいと思います。なお、indexの複数形はindicesとindexesの二つがあり、
chromium code searchだとそれぞれ3365件612件です

Copy link

Choose a reason for hiding this comment

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

個人的には num_to_indices が良いと思います。 number という英単語については、入力の変数名が nums と number を省略して複数形にした形のため、省略してしまってよいと思います。また、あくまで個人的な好みになりますが、複数の値が含まれる変数の変数名は、複数の値が含まれることを明示するため、複数形で終えるようにしています。

Choose a reason for hiding this comment

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

@nodchip 個人的な好みと強調されているところすみません、こちら、num一つに対しindex一つの1対1のmapだと思うのですが、それでも複数形にするということでしょうか??
(number_to_index) + -es(複数形)というイメージですかね??
numの省略に関しては同意です(統一するのがいいと思います)

Copy link

Choose a reason for hiding this comment

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

はい、変数の中に複数の値が含まれる場合は、変数名の最後の単語を複数形にしています。この規則に違和感を持たれる方がいるであろうことも承知しています。また、チームの平均的な書き方と異なっているのであれば、チームの平均的な書き方に合わせようとも考えています。

Choose a reason for hiding this comment

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

@nodchip なるほどです!ありがとうございます!

Choose a reason for hiding this comment

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

一応chromiumでの使用例を載せておきます
単数形
複数形

Copy link

Choose a reason for hiding this comment

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

ありがとうございます。揚げ足取りになって試合申し訳ないのですが、 data は複数形です。数的には大勢に影響はないため、無視していただいて大丈夫だと思います。

for i, num in enumerate(nums):

Choose a reason for hiding this comment

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

好みのレベルですが、今回の問題に限ってはindexそのものを扱っているのでiではなくindexとしても良いと思いました。

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から見て孫)となる。
- 覚える必要はないと思うが、大体の関係性は把握しておきたい。
Copy link

Choose a reason for hiding this comment

The 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
- エラーの仕組みは詳しく知らなかったため、勉強になった。
24 changes: 24 additions & 0 deletions arai60_11_2.md
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')
```