-
Notifications
You must be signed in to change notification settings - Fork 0
198. House Robber #36
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
return 0 | ||
if len(nums) == 1: | ||
return nums[0] | ||
max_money_so_far = [nums[0], max(nums[:2])] |
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.
素直に2変数使うほうが読みやすいかなと思もいました。自分は2周してようやく何をしているかが分かりました。
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.
なるほど、ありがとうございます。
漸化式を配列で表したときの末尾2つ、というイメージで書いていたのであまり読みにくい発想なかったんですが、その考え方を共有できないと分かりにくくなるかもと思いました。
変数名ちょっと迷うんですが、左から順に更新するイメージでlast_max_money, second_last_max_moneyとかですかね...更新するときは
for i in range(2, len(nums)):
max_money = max(last_max_money, second_last_max_money + nums[i])
second_last_max_money = last_max_money
last_max_money = max_money
みたいな。
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.
Invariant
Initial:
max_money_so_far: [max_money[0], max_money[1]]
loop i start:
max_money_so_far: [max_money[i - 2], max_money[i - 1]]
loop i end:
max_money_so_far: [max_money[i - 1], max_money[i]]
After loop:
max_money_so_far: [max_money[n - 2], max_money[n - 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.
そうですね、そのイメージでした。
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.
Loop invariantをコメントに入れたら、分かりやすくなりそうでしょうか。(max_moneyはどこかで定義する)
max_money_so_far = [nums[0], max(nums[:2])] # max_money_so_far: [max_money[0], max_money[1]]
for i in range(2, len(nums)):
# max_money_so_far: [max_money[i - 2], max_money[i - 1]]
prev = max_money_so_far[1]
max_money_so_far[1] = max(max_money_so_far[1], max_money_so_far[0] + nums[i])
max_money_so_far[0] = prev
# max_money_so_far: [max_money[i - 1], max_money[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.
so_far はこの場合はそりゃそうだろう感がありませんか。
この場合の特徴は、最後を使う場合、使わない場合ですかね。
|
||
### ③ | ||
|
||
逆からメモ化再帰。こっちの方が素直か。rob_helperはmax_robbable_money_untilという名前でもいいかもしれない。 |
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.
こちらが自然な気がします。再帰を使う場合はTop Downのアプローチが向いていると思います。②はBottom Upだけど再帰を使っていて見慣れなかったです。
if len(nums) == 1: | ||
return 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.
このコードだと len(nums) == 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.
たしかに...!気づきませんでした、ありがとうございます。
でもこのコードで漸化式の初項しかない入力が来たときに、max_money_so_farに値を2つ入れるのちょっと違和感あります...特別な場合を無理やり同じ処理にまとめているというか。
https://leetcode.com/problems/house-robber/description/