Skip to content

0001. two sum #2

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

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
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
9 changes: 9 additions & 0 deletions 0001. Two Sum/1st_step.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
ans = []
for i in range(len(nums)-1):
for j in range(i+1, len(nums)):
if nums[i] + nums[j] == target:
ans = [i,j]
return ans
return ans
7 changes: 7 additions & 0 deletions 0001. Two Sum/2nd_step.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
pair_index = {}
for i, num in enumerate(nums):
if target - num in pair_index:
return [i, pair_index[target - num]]
pair_index[num] = i
7 changes: 7 additions & 0 deletions 0001. Two Sum/3rd_step.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
pair_index = {}
for i, num in enumerate(nums):
if target - num in pair_index:
return [i, pair_index[target - num]]
pair_index[num] = i
115 changes: 115 additions & 0 deletions 0001. Two Sum/Note.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# 問題概要
問題: 1. Two Sum

https://leetcode.com/problems/two-sum/description/
Copy link

Choose a reason for hiding this comment

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

問題のリンクはプルリクのコメントに記載していただけた方がありがたいです。

Copy link
Owner Author

Choose a reason for hiding this comment

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

ありがとうございます。反映しました!


言語: Python

# Step1

かかった時間:15min

思考ログ:
- 問題を理解する。
- 配列numsと数値targetが与えられる。配列から取り出した2つの要素の合計がtargetとなるような配列のindexを返す問題
- 配列の要素は2つ以上
- 有効な答えは必ず存在する
- どのような解き方ができるか
- 愚直に配列をループさせて和がtargetとなる要素のindexを返せばいけそう
- 2つのループを用意する。iは0~n-1、jは1~nまで回す
Copy link

Choose a reason for hiding this comment

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

時間計算量や実行時間は考慮しましたか?

Copy link
Owner Author

Choose a reason for hiding this comment

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

ご指摘ありがとうございます。
考慮できていなかったです。。solutionを比較する際に重要な指標になるかと思いますので、今後は時間計算量や実行時間も考慮して解答方法を考えたいと思います。

- Pythonの使い方についてもおさらいしておく
- for
- https://www.w3schools.com/python/python_for_loops.asp
- range:The range() function returns a sequence of numbers, starting from 0 by default, and increments by 1 (by default), and stops before a specified number.
- https://www.w3schools.com/python/ref_func_range.asp
- len:Return the number of items in a list
- https://www.w3schools.com/python/ref_func_len.asp

```python
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
ans = []
for i in range(len(nums)-1):
for j in range(i+1, len(nums)):
if nums[i] + nums[j] == target:
ans = [i,j]
Copy link

Choose a reason for hiding this comment

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

, の後にスペースを 1 つ入れることをお勧めします。
https://google.github.io/styleguide/pyguide.html#s3.6-whitespace

No whitespace before a comma, semicolon, or colon. Do use whitespace after a comma, semicolon, or colon, except at the end of the line.

Copy link
Owner Author

Choose a reason for hiding this comment

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

上記リンク先について知らなかったです…
全く意識できていなかったので、今後は[i, j]と記載したりStyle Guidesを意識した体裁にしていきたいと思います!

return ans
return ans
```
疑問点:
- 時間計算量をさらに減らすことは可能なのか?
- 他のアプローチで解くことは可能?
- 返却する変数の命名は妥当?
- ```ans```変数を定義せずに```return```することもできるがどちらが良さそうか
- 定義する場合は、その変数を使いまわすことが可能だが、今回は特に不要そう
- 定義しない場合は行数を減らすことができる

参考リンク
-

# Step2
かかった時間:30min

思考ログ
- まずは過去に実装している人の解き方をいくつか確認してみる
- 解法について
- 2重ループせずにhashmapを利用する方法
- 値とindexのペアをhashmapに保持する
- hashmapをループして```target```と値の差を取り、hashmapに存在する場合はループ時のindexとhashmapのindexを返す
- 存在しない場合はhashmapに追加する
- その他
- 利用する言語を明記した方が良さそう
- 時間計算量や空間計算量を意識できていなかった
- 上記踏まえもう少し深掘りして理解を深める
- hashmapとは?
- キーと値を組み合わせたdictionary(辞書)
- 値とindexを持たせることで解くことが出来そう
- 時間計算量(Time Complexity)とは?
- ```「プログラムの実行に必要な計算のステップ数が入力に対してどのように変化するか」という指標を時間計算量といいます。 計算ステップ数とは、四則演算や数値の比較などの回数です。```
- 2重ループはO(n^2)、1重のループはO(n)、ループすることがないような処理はO(1)、分割して探索するアルゴリズムを利用する際はO(logN)といった計算量になる
- 空間計算量(Space Complexity)とは?
- ```「プログラムの実行に必要なメモリの量が入力に対してどのように変化するか」という指標を空間計算量といいます。```
- 2次元配列はO(n^2)、1次元配列はO(n)、変数の格納のみの場合はO(1)といった計算量になる
- https://atcoder.jp/contests/apg4b/tasks/APG4b_w?lang=ja
- 時間計算量と空間計算量はLeetCodeの```submit```後の実行結果から確認できるので答え合わせに良さそう。(```Runtime```や```Memory```の```Analyze Complexity```)※プレミアムに加入が必要なのか・・・
Copy link

Choose a reason for hiding this comment

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

というよりもレビューに出すときに一緒に書いておけば、間違っている場合誰かが指摘してくれると思います

Copy link
Owner Author

Choose a reason for hiding this comment

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

その方が良さそうですね、、自分で考えて記載するようにします!

- enumerateとは?
- indexと要素を返してくれる関数。hashmapのループに利用できそう。
- https://docs.python.org/3/library/functions.html#enumerate

```python
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
pair_index = {}
for i, num in enumerate(nums):
if target - num in pair_index:
return [i, pair_index[target - num]]
pair_index[num] = i
```

# Step3
かかった時間: 5min

上記を書き直して実装。

思考ログ
- numsとnumが似ているのは混同する可能性があるので他の命名にした方が良さそう?

Choose a reason for hiding this comment

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

自分はnum-> nでもこの場合は十分伝わりそうです

Copy link
Owner Author

Choose a reason for hiding this comment

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

ありがとうございます!nはnumberを表すのは自明ですもんね、、
かつ、numnumsを混同する可能性があるという点で、nの方がより良いように感じますね。。

- pair_indexは分かりやすい名前なのか?
Copy link

@Yoshiki-Iwasa Yoshiki-Iwasa Aug 8, 2024

Choose a reason for hiding this comment

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

個人的にはpair_indexだとわかりにくいかなと思います。Tupleやpairを想起させられるので

例えば、num_to_indexにして、complement = target - num に一度バインドした後で
if complement in num_to_indexにすると意図が伝わりやすいかなと思いました

Copy link
Owner Author

Choose a reason for hiding this comment

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

ありがとうございます。別コメントにもありましたが、確かにpair_indexだとindexのペアが格納されているように感じますね、、
参考例もありがとうございます。あくまで数値とindexを持っていることが分かるような変数名にしたいと思います!

- 有効な答えは必ず存在するという前提からループを抜けてからのreturnは不要と判断

```python
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
pair_index = {}
Copy link

Choose a reason for hiding this comment

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

自分がPythonに慣れていないことが原因ではあるのですが、最初ここを読んだ時、変数名もあってか、

pair_index = {(i0, j0), (i1, j1), ...}

のようにインデックスの組みを格納するset型の変数かと思ってしまいました。調べたら、空のsetを宣言するときは必ずset()を使うらしいので、Python慣れている人なら= {}を見てすぐ辞書型とわかるかもしれませんが、dict()の方がわかりやすいと思いました。
Pythonに慣れていない人が見たら、という視点なのでそんなこともないのかもしれません

Copy link

Choose a reason for hiding this comment

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

ここら辺見てもらえると良いかと思います。dict()の場合は追加の関数呼び出しのオーバーヘッドがあるため、Pylintなどだと{}を使うようにメッセージが出るらしいです。
rihib/leetcode#8 (comment)

Copy link
Owner Author

@ryo-devz ryo-devz Aug 9, 2024

Choose a reason for hiding this comment

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

コメント&補足ありがとうございます。
pyhonって書き方が簡易的なので分かりにくさはありますよね・・・

dict(){}の違いは全く意識したことがなかったですが、{}の方が速くよく使われるのですね!
dict()を使った際は{}を使うようにメッセージが出るようになっているっぽい。
→これも全く知らなかったです…{}の方がより速いという点で推奨されているようなので、{}を採用するようにします!そのうえで変数名については分かりやすい命名になるよう工夫したいと思います。

for i, num in enumerate(nums):
if target - num in pair_index:
return [i, pair_index[target - num]]
pair_index[num] = i
Comment on lines +101 to +106

Choose a reason for hiding this comment

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

この関数の処理、return 文まで到達しない可能性がありますね。Leetcode の問題文には、そのようなことになる値が引数として渡されないとありますが、その旨が関数の実装にも反映されていた方がいいように思います。
以前自分が Java で実装した際、return 文まで到達しなかった際に通る関数の最下部にて exception を throw するようにしてみましたが、Python で同等の処理を書いておくといったことをしてもいいのかなと思いました (参考)。

Copy link

Choose a reason for hiding this comment

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

なかった場合、何が返るかは答えられますか。実行して確認してみましょう。

Copy link
Owner Author

@ryo-devz ryo-devz Aug 9, 2024

Choose a reason for hiding this comment

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

ありがとうございます。なかった場合は空のListの[]が返却されますね。。
問題文の前提上は必ずreturnされるとしても、確かにこの関数だけを見るとreturnされない可能性があるのでは?という迷いが生じますね。
そういった意味で例外処理をするなどで関数内で最後まで到達することがあり得ない実装にしておいた方がよさそうですね・・勉強になります!

```

# Step4
- レビューを受けて修正を行う

```python


```
53 changes: 0 additions & 53 deletions 1. Two Sum/Note.md

This file was deleted.