-
Notifications
You must be signed in to change notification settings - Fork 0
213. House Robber II #38
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
base: main
Are you sure you want to change the base?
Conversation
| if len(nums) <= 1: | ||
| return nums[0] | ||
|
|
||
| def _rob_in_line(l: int, r: int) -> int: |
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.
in_lineはどういった意図での命名ですか?_rob_rangeでどうでしょうか?
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.
あ、サイクルに対してin lineってことですね。これで良さそうです。
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.
有難うございます。
コメントがあった方が良かったかもしれません。。
| return nums[0] | ||
|
|
||
| def _rob_in_line(l: int, r: int) -> int: | ||
| assert 0 <= l < r <= len(nums) |
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.
inclusiveかexclusiveなのか少し考えないと分かりませんでした。range()のパラメータに合わせて、start, stopとかでしょうか?
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.
確かに半開区間かどうか分かりにくいですね。。
ご提案いただいたstart, stopがとてもしっくりきます。今後使おうと思います。
| def _rob_in_line(l: int, r: int) -> int: | ||
| assert 0 <= l < r <= len(nums) | ||
| # l番目の家までに盗める最大金額をl番目の家に盗みに入るかどうかで場合わけ | ||
| max_money_skipped_last = 0 |
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.
max_money_は省略しても良いでしょう。
| # l番目の家までに盗める最大金額をl番目の家に盗みに入るかどうかで場合わけ | ||
| max_money_skipped_last = 0 | ||
| max_money_robbed_last = 0 | ||
| while l < r: |
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.
for l in range(r):for i in range(l, r)と同じですか?
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.
for i in range(l, r)です
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.
同じです。
forループの方が自然ですね。。頭から抜けてました。
なぜかポインタlをwhileループの中で操作するイメージが強くあり、この実装に落ちました。
step4の追加 命名とループの書き方の修正
| numsの端が繋がってはいけないという制約を外して最大の金額を計算する | ||
| ''' | ||
| # numsのi番目を盗むかどうかで場合わけ | ||
| max_money_skipped_i = nums[0] |
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.
変数の意味が伝わりにくく感じました。特に i が何を指すのか分かりませんでした。 i 番目の家で盗まなかった場合の最大の金額を表したのでしょうか?もしそうだとすると、この時点では i が登場していないため、何を指しているのか分かりにくく感じます。
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.
有難うございます。
実は、House Robberで同様のご指摘をいただいていたのですが、step1は既に書いてしまっていたので、敢えて残していました。
ただ、振り返ってみるとhoge_iのような命名を良くしがちなので、注意したいと思います。
step2以降では諸々のコメントを反映しています。
| max_money_skipped_i = nums[0] | ||
| max_money_robbed_i = nums[1] | ||
| for i in range(2, len(nums)): | ||
| max_money_skipped_i, max_money_robbed_i = ( |
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.
複数代入を行うより中間的な変数を設けるなどした方が読みやすいと感じました。
Pythonでは一般的でしたらすみません🙇
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.
有難うございます。
同様のご指摘を頂いているのでRyotaro25さんの感覚が一般的だと思います。
|
|
||
| 時間計算量:O(N) | ||
|
|
||
| 空間計算量:O(N) |
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.
使われているのはmax_money_skipped_iとmax_money_robbed_iの変数(配列ではない)だけであるため、空間計算量はO(1)ではないでしょうか?
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.
L33で配列をコピーしているのでO(N)ですね。
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.
@liquo-rice (@TORUS0818 ) 2回スライスを用いてますね。失礼しました🙇
| - ここでは面倒なのでやらないが、実務で使ってみよう | ||
| - インデックスでやるか配列を投げるか問題 | ||
| > begin_index, end_indexを引数に持つように書いたが、このくらいならO(n)かけてコピーした配列を引数に持たせるようにした方が処理が分かりやすくていいかもしれない | ||
| > (Pythonであまりスライスによるコピーコストを気にしても意味が薄い場面も多そう。o(n)な計算量にしたいときはそれが律速になるので避けるが)。 |
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.
C++ だと std::ranges::subrange というのがありますね。
Python でも標準では存在しませんが作ろうと思えば作れます。
https://stackoverflow.com/questions/3485475/can-i-create-a-view-on-a-python-list
class を作らずに range から __getitem__ を書き換えれば楽かなと思ったのですが、__getitem__ は後から書き換えられないらしいので class を作らざるを得ないでしょう。
https://stackoverflow.com/questions/57413453/is-it-possible-to-override-getitem-at-instance-level-in-python
Python のスライスコピーはネイテイブコードなので他のところよりも感覚50倍速く、再帰などで繰り返し呼ばないならば大きな問題はないというのはそうでしょう。
https://leetcode.com/problems/house-robber-ii/description/