Skip to content
Merged
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
17 changes: 17 additions & 0 deletions 1.Two Sum/loop.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {

vector<int> two_indices;
for (int i = 0; i < numbers.size(); i++) {
for (int j = 0; j < numbers.size(); j++) {
if (i != j && target - numbers[i] - numbers[j] == 0) {
Comment on lines +7 to +8
Copy link
Copy Markdown

@erutako erutako Jun 11, 2024

Choose a reason for hiding this comment

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

loopで書くなら、内側のfor文のカウント変数の初期化を int j = i + 1のようにして、全探索にしても余分な計算は省くとよいのかなと思いましたmm
これをすればif文の条件で i != jがいらなくなるので、そこも読みやすくなってメリットがあるかなと思います。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

@erutako
ありがとうございます!確かに初めからループさせる必要ないですね。。。
loop2.cppにて実装しました🙇
reflecting review

two_indices.push_back(i);
two_indices.push_back(j);
return two_indices;
}
}
}
return two_indices;
}
};
17 changes: 17 additions & 0 deletions 1.Two Sum/loop2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {

vector<int> two_indices;
for (int i = 0; i < numbers.size(); i++) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

結果は同じですが、i < numbers.size() - 1とした方が良さそうです。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

j = i + 1とするならこちらの方がいいですね。ループの回数もきちんと意識します。

for (int j = i + 1; j < numbers.size(); j++) {
if (target - numbers[i] - numbers[j] == 0) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

普通はnumbers[i] + numbers[j] == targetとしませんか?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

@liquo-rice そうですね。他の解法で使ったremainingにつられてました。。。

two_indices.push_back(i);
two_indices.push_back(j);
return two_indices;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

return {i, j}

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

@liquo-rice
わざわざ変数に入れる必要ないですね。
下記にてloop3.cppを追加しました。
3bd35d9

}
}
}
return two_indices;
}
};
14 changes: 14 additions & 0 deletions 1.Two Sum/loop3.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {

for (int i = 0; i < numbers.size() - 1; i++) {
for (int j = i + 1; j < numbers.size(); j++) {
if (numbers[i] + numbers[j] == target) {
return {i, j};
}
}
}
return {};
}
};
49 changes: 49 additions & 0 deletions 1.Two Sum/memo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
## ステップ1
forを2重で回せば解けたけどO(n^2)となってしまう
どうすれば計算量を抑えられるのかが今回の問題だと思う。
時間
O(n^2)
空間
O(1)

~~問題のジャンルがhash mapなのでmapを使った解法を考える~~
liquo-riceさんから指摘があったようにMapは平衡二分探索木、unordered_mapがhash map

<数値、インデックス>でmapを作りこれをループで回して
targetから数値を引いた数をもつindexを探せばO(1)ですみそう

Keyが重複する場合の回答の見つけ方が分からなかったので回答を参照
https://leetcode.com/problems/two-sum/
ループの最後に挿入することで
重複を上書きする前に、keyとvalueを見つけることができる
~~時間~~
~~O(n)~~
空間
O(n)

時間
mapのcontainsを使う場合(log n)なので合計O(n log n)
unordered_mapのcontainsを使う場合はO(n)なのでO(n^2)
https://en.cppreference.com/w/cpp/container/unordered_map/contains
## ステップ2
・解なしの場合も考慮する、今回だと{}をreturnすることで差別化
https://github.com/colorbox/leetcode/pull/3#discussion_r1519068995
https://github.com/cheeseNA/leetcode/pull/1

・命名について
numsとnumbersどちらも存在しているのは気持ち悪いような気がするのでどちらかに統一
https://github.com/sakupan102/arai60-practice/pull/12

・算術演算子についてもスタイルガイドが存在する
https://github.com/fhiyo/leetcode/pull/14

## 他の解法
2重ループの回答はloop.cppに実装

## Discordなど
私は紙と鉛筆でやるんだったら、カードをソートして、頭と尻から辿っていくと思いますね。
はじめに、一番初めと一番最後に着目します。
着目しているものを足します。
目標よりも小さかったら、前の方の着目しているのを一つ後ろにずらします。
目標よりも大きかったら、後ろの方の着目しているのを一つ前にずらします。
https://discord.com/channels/1084280443945353267/1183683738635346001/1187326805015810089
16 changes: 16 additions & 0 deletions 1.Two Sum/step1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int, int> numbers_and_index;
vector<int> two_indices;
for (int i = 0; i < nums.size(); i++) {
int remaining = target - nums[i];
if (numbers_and_index.contains(remaining)) {
return {numbers_and_index[remaining], i};
}
numbers_and_index.insert({nums[i], i});
}

return two_indices;
}
};
15 changes: 15 additions & 0 deletions 1.Two Sum/step2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
map<int, int> numbers_to_index;
for (int i = 0; i < numbers.size(); i++) {
int remaining = target - numbers[i];
if (numbers_to_index.contains(remaining)) {
return {numbers_to_index[remaining], i};
}
numbers_to_index.insert({numbers[i], i});
}

return {};
}
};
14 changes: 14 additions & 0 deletions 1.Two Sum/step3.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
map<int, int> numbers_to_index;
Copy link
Copy Markdown

@erutako erutako Jun 11, 2024

Choose a reason for hiding this comment

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

細かいですが、numbersは複数形でindexは単数形なのが気になりましたmm
個人的にはmapの一つのエントリを指す名前の方が直感的なので単数形でnum_to_indexとかが良さそうかなと思いましたmm

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

@erutako
step5に追加しました。統一感の意識はしておかないとですね。。。
reflecting review

for (int i = 0; i < numbers.size(); i++) {
int remaining = target - numbers[i];
if (numbers_to_index.contains(remaining)) {
return {numbers_to_index[remaining], i};
}
numbers_to_index[numbers[i]] = i;
}
return {};
}
};
21 changes: 21 additions & 0 deletions 1.Two Sum/step4.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
// 100mおきの数字のインデックスを記録しつつtargetを超える大きさなのか、
// target以下なのかの情報とtargetまであと何の数字が必要か書いて渡すと思います。
map<int, int> numbers_to_index;
for (int i = 0; i < numbers.size(); i++) {
int remaining = target - numbers[i];
numbers_to_index[remaining] = i;
}

for (int i = 0; i < numbers.size(); i++) {
int target_remaining = numbers[i];
if (numbers_to_index.contains(target_remaining) && numbers_to_index[target_remaining] != i) {
return {numbers_to_index[target_remaining], i};
}
}
return {};
}
};

14 changes: 14 additions & 0 deletions 1.Two Sum/step5.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
map<int, int> num_to_index;
for (int i = 0; i < numbers.size(); i++) {
int remaining = target - numbers[i];
if (num_to_index.contains(remaining)) {
return {num_to_index[remaining], i};
}
num_to_index[numbers[i]] = i;
}
return {};
}
};
18 changes: 18 additions & 0 deletions 1.Two Sum/step6.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
if (nums.empty()) {
return {};
}

map<int, int> num_to_index;
for (int i = 0; i < nums.size(); i++) {
int remain = target - nums[i];
if (num_to_index.contains(remain)) {
return {num_to_index[remain], i};
}
num_to_index[nums[i]] = i;
}
return {};
}
};