Skip to content
Open
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
59 changes: 59 additions & 0 deletions 198/198.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
## 何も見ずに解いてみる

```cpp
class Solution {
public:
int rob(std::vector<int>& nums) {
int max_with_last_broken = 0;
int max_with_last_unbroken = 0;
for (const int num : nums) {
int next_max_with_last_broken = max_with_last_unbroken + num;
int next_max_with_last_unbroken = std::max(max_with_last_broken, max_with_last_unbroken);
max_with_last_broken = next_max_with_last_broken;
max_with_last_unbroken = next_max_with_last_unbroken;
}
return std::max(max_with_last_broken, max_with_last_unbroken);
}
};
```

## 他の人のコードを見てみる

https://github.com/tokuhirat/LeetCode/pull/35/files
https://github.com/irohafternoon/LeetCode/pull/38/files
https://github.com/Ryotaro25/leetcode_first60/pull/36/files
https://github.com/Jikuhara/LeetCode/pull/7/files

下のようにすれば変数は3つで書くことができた。
ただ、どの値がどの値に依存しているか気にしなくて良いという意味では変数を4つ用意してしまった方が読みやすい気もする。

```cpp
for (const int num : nums) {
int next_max_with_last_broken = max_with_last_unbroken + num;
max_with_last_unbroken = std::max(max_with_last_broken, max_with_last_unbroken);
max_with_last_broken = next_max_with_last_broken;
}
```

変数名について、lastという言い方はnumsの中の一番最後という位置を連想してしまうかもしれない。prevなどの方が良いかも?

一次元DPを見て思ったが、もしかしたら最後に入っているか入っていないかで変数を分けるよりも、単純に一個前までのmax、二個前までのmaxとして変数に保存した方がわかりやすいかもしれない。
ただ、抽象的になりすぎて何のことかわからなくなる可能性はありそうで悩ましい・・・

## 最終コード

```cpp
class Solution {
public:
int rob(std::vector<int>& nums) {
int prev_max = 0;
int current_max = 0;
for (const int num : nums) {

Choose a reason for hiding this comment

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

あまりわかっていないコメントで恐縮ですが、counst auto& を使うのもありでしょうか?

Copy link
Owner Author

@potrue potrue Aug 5, 2025

Choose a reason for hiding this comment

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

autoはコンパイル時に型を自動で推論するものなので、コンパイル後のプログラムはconst auto&はconst int&と同じになるのではないかと認識しています。

&をつけると参照渡しになり、変数のコピーではなく変数のメモリアドレスが渡されるようなのですが、これをつけずに値渡しにしておくと、値のサイズが小さい場合にはCPUのレジスターに直接書き込まれ、メモリアドレスを介してアクセスする場合に比べて高速になる場合があるようです。intなどサイズが小さい値の場合は、アドレスを渡しても値のコピーを渡しても必要なサイズが同じあるいは値のコピーを渡すほうが小さく、上記のパフォーマンス高速化の観点から見て値渡し(&をつけずにconst intまたはconst autoとする)の方が良いとされているのだと思います。
(間違っていたらすみません)

maeken4/Arai60#9 (comment)
#36 (comment)

Choose a reason for hiding this comment

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

丁寧に教えていただきありがとうございます!

int next_max = std::max(current_max, prev_max + num);
prev_max = current_max;
current_max = next_max;
Comment on lines +52 to +54

Choose a reason for hiding this comment

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

これはこれでありかなと思いはしますが、今見ている num を基準に考えると、1 軒前まで、2 軒前まで、現在まで max を見ている、と考えたほうが (個人的には) 理解しやすいように思います。

Copy link
Owner Author

@potrue potrue Aug 6, 2025

Choose a reason for hiding this comment

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

これ少し迷ったのですが、最後にprev_maxをリターンすることになるのがちょっと気に食わなくてこちらにしてしまいました。。

}
return current_max;
}
};
```