Skip to content

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

198. House Robber #36

wants to merge 1 commit into from

Conversation

fhiyo
Copy link
Owner

@fhiyo fhiyo commented Jul 6, 2024

return 0
if len(nums) == 1:
return nums[0]
max_money_so_far = [nums[0], max(nums[:2])]

Choose a reason for hiding this comment

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

素直に2変数使うほうが読みやすいかなと思もいました。自分は2周してようやく何をしているかが分かりました。

Copy link
Owner Author

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

みたいな。

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]]

Copy link
Owner Author

Choose a reason for hiding this comment

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

そうですね、そのイメージでした。

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]]

Copy link

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という名前でもいいかもしれない。

Choose a reason for hiding this comment

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

こちらが自然な気がします。再帰を使う場合はTop Downのアプローチが向いていると思います。②はBottom Upだけど再帰を使っていて見慣れなかったです。

Comment on lines +126 to +127
if len(nums) == 1:
return nums[0]

Choose a reason for hiding this comment

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

このコードだと len(nums) == 1を特別扱いする必要はないと思いました。

Copy link
Owner Author

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つ入れるのちょっと違和感あります...特別な場合を無理やり同じ処理にまとめているというか。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants