-
Notifications
You must be signed in to change notification settings - Fork 0
1. Two Sum (from Grind 75 questions Easy-Array) #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
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,46 @@ | ||
初見ではないものの、時間が空いてしまったので再度STEP1からやり直す。 | ||
|
||
### 課題の言語化(できたら現実世界で同じ課題を再現する) | ||
数字が書かれたカードが何枚か(nums)と、壁に書かれた一つの数字(target)がある。 | ||
2枚のカードを選んで書かれている数字を足し算すると壁に書かれた数字となるようなカードの番号を見つける。 | ||
そのようなカードの組み合わせは一つしか存在せず、同じカードを2回選ぶことはできない。 | ||
|
||
### 思考記録 | ||
1枚のカードを固定して、残りのカードを1枚ずつ見て、足すと壁に書かれた数字になる組み合わせを探す。 | ||
残り5分なので一旦この方針でコードを書く。 | ||
|
||
### 計算量 | ||
#### 時間計算量 | ||
2 <= nums.length <= 10^4だから、O(n^2)でも許してもらえそう。 | ||
多分ほんとはもっと少ない計算量でいける。 | ||
#### 空間計算量 | ||
|
||
### コード | ||
```Java | ||
class Solution { | ||
public int[] twoSum(int[] nums, int target) { | ||
int[] indices = new int[2]; | ||
boolean isPairFound = false; | ||
for (int i = 0; i < nums.length; i++) { | ||
if (isPairFound) { | ||
break; | ||
} | ||
for (int j = i + 1; j < nums.length; j++) { | ||
if (nums[i] + nums[j] == target) { | ||
indices[0] = i; | ||
indices[1] = j; | ||
isPairFound = true; | ||
break; | ||
} | ||
} | ||
} | ||
return indices; | ||
} | ||
} | ||
``` | ||
|
||
### 感想(他の方のコードなどを読んで) | ||
- 今回は必ず解が見つかる条件だったが、見つからないときにどのような値を返すかは考慮してよかった | ||
- 謎にbreakで抜けてからreturnしているが、普通にその場でreturnで良かった | ||
- One-passのHash Tableはなるほど。確かに仮に(1,5)が答えだったとして、1のときは5がハッシュテーブルになくてループが続くけど、5のときは必ず1がハッシュテーブルにあるので答えが見つかるから、インデックス順に答え合わせしながらハッシュテーブルを作れば答えを見逃すことがない。 | ||
- 髪と鉛筆でやるなら、カードをソートして、頭と尻からたどるというのもなるほど。現実世界でやろうとしたときにこういうアイデアが今は浮かばない。 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
### 課題の言語化(できたら現実世界で同じ課題を再現する) | ||
> 数字が書かれたカードが何枚か(nums)と、壁に書かれた一つの数字(target)がある。 | ||
2枚のカードを選んで書かれている数字を足し算すると壁に書かれた数字となるようなカードの番号を見つける。 | ||
そのようなカードの組み合わせは一つしか存在せず、同じカードを2回選ぶことはできない。 | ||
|
||
一旦カードに書かれた数字が0-100だと限定し考える。 | ||
0-100の数値に対応する10x10の表のようなカード置き場を用意する。 | ||
カードを順に見ていき、壁に書かれた数字-カードに書かれた数字の数の表のマスを見て、数字がなければいま見ているカードに書かれた数字のマスにそのカードが何番目に見たカードかメモする。 | ||
順に繰り返すと、どこかで壁に書かれた数字-カードに書かれた数字の数の表のマスを見たときに数字がメモされているときがくるはず。 | ||
そのときに、マスにメモされている数字と今見ているカードが何番目かの数字が求められている答え。 | ||
|
||
### 思考記録 | ||
課題の言語化でだいぶコードのイメージがついた。 | ||
とりあえず書いてみる。 | ||
ここまでで11分。 | ||
今回は値が見付からなかったときは`[-1, -1]`で返すことにする。 | ||
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. Javaならnullを返すのも一つかもですね 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.
うーむ難しいですよね...正直、よく分からないです。入力が前提条件を満たさないときに特殊な値を返すとして、nullが返るのと[-1, -1]が返るのどちらがびっくりしないかという話かなと思っていて、Javaだったら前者だろうか...?と思ってコメントした感じでした。Optionalで返したいの分かります。 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(N)でいける | ||
#### 空間計算量 | ||
こちらもO(N)でいける | ||
|
||
### コード | ||
```Java | ||
import java.util.Hashtable; | ||
import java.util.Objects; | ||
|
||
class Solution { | ||
public int[] twoSum(int[] nums, int target) { | ||
Hashtable<Integer, Integer> table = new Hashtable<>(); | ||
for (int i = 0; i < nums.length; i++) { | ||
int requiredNum = target - nums[i]; | ||
Integer requiredIdx = table.get(requiredNum); | ||
if (Objects.isNull(requiredIdx)) { | ||
table.put(nums[i], i); | ||
} else { | ||
return new int[]{i, requiredIdx.intValue()}; | ||
} | ||
} | ||
return new int[]{-1, -1}; | ||
} | ||
} | ||
``` | ||
|
||
### 感想(他の方のコードなどを読んで) | ||
- 課題の言語化はハッシュテーブルありきで言語化したので、あまり意味はなかったかも?でも、ハッシュテーブルでやろうとしていることのイメージを具体化するうえでは良かった。 | ||
- 提出コードを書ききるまでに結局40分かかった。途中でランタイムエラーがでたり、ハッシュテーブルの実装を調べたりしていたので時間の測り方としては良くなかったかも。 | ||
- HashTableのinitialCapacityを増やして実行すると実効速度は早くならない一方で、メモリ使用量は増えるだけだった。意外。数値の範囲は割と大きいのに少しずつハッシュテーブルを大きくするほうが良いのか?実行時に与えられている数値にもよるか。 | ||
- HashTableはスレッドセーフだったり色々サポートしてくれる分HashMapよりも遅い?nullをサポートしたい、マルチスレッド環境で動かしたいというニーズがなければHashMapで良さそう。 | ||
- Objects.isNullを使っていたけど、containsKeyのほうがシンプル。 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
### 課題の言語化(できたら現実世界で同じ課題を再現する) | ||
step1,2でできたためSKIP | ||
|
||
### 思考記録 | ||
HashMapでstep1,2の課題の言語化をイメージしながら実装する。 | ||
さっきSTEP2を終えたばかりなので、すぐに手が動く。 | ||
|
||
### 計算量 | ||
#### 時間計算量 | ||
O(N) | ||
#### 空間計算量 | ||
O(N) | ||
|
||
### コード | ||
```Java | ||
class Solution { | ||
public int[] twoSum(int[] nums, int target) { | ||
HashMap<Integer, Integer> map = new HashMap<>(); | ||
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. 特別な理由がない限り、広いinterfaceで定義したほうが良さそうですね! |
||
for (int i = 0; i < nums.length; i++) { | ||
int requiredVal = target - nums[i]; | ||
if (map.containsKey(requiredVal)) { | ||
return new int[]{i, map.get(requiredVal)}; | ||
} | ||
map.put(nums[i], i); | ||
} | ||
|
||
// 値が見つからなかったとき | ||
return new int[]{-1, -1}; | ||
} | ||
} | ||
``` | ||
### かかった時間 | ||
5分26秒 | ||
|
||
### 感想(他の方のコードなどを読んで) | ||
- HashTableよりHashMapのほうが1ms早くなった。このあたりも仕様を把握して使い分けできるようにしたい。 | ||
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. もしleetcodeで出力されたRuntimeの値を見てるんでしたら、結構ブレが大きいので大きな差でなければ気にしないでいいかもです 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. 確かにおっしゃるとおりですねmm |
||
- IDEになれているので、配列の初期化でSyntaxErrorを出したりして時間を使った。数をこなせばSyntaxErrorでつまずくところは減らしてスピードを上げられそう。 | ||
- 今日は短期記憶で頭の中に解答のコードが入ってしまったので、しばらく寝かせてまた解いてみる。 |
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.
これは違和感が結構ありますね。
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.
そうですよねmm
普段あまりしないのですが、がむしゃらに考えてコード書いていたら最終的によくわからないコードが誕生していましたmm
自分もかなり違和感を持つコードだったので、すぐに気付けるようにトレーニングしますmm