Skip to content

Conversation

@TORUS0818
Copy link
Owner

if len(nums) <= 1:
return nums[0]

def _rob_in_line(l: int, r: int) -> int:

Choose a reason for hiding this comment

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

in_lineはどういった意図での命名ですか?_rob_rangeでどうでしょうか?

Choose a reason for hiding this comment

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

あ、サイクルに対してin lineってことですね。これで良さそうです。

Copy link
Owner Author

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)

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とかでしょうか?

Copy link
Owner Author

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

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:
Copy link

@liquo-rice liquo-rice Dec 5, 2024

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)と同じですか?

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)です

Copy link
Owner Author

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

Choose a reason for hiding this comment

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

変数の意味が伝わりにくく感じました。特に i が何を指すのか分かりませんでした。 i 番目の家で盗まなかった場合の最大の金額を表したのでしょうか?もしそうだとすると、この時点では i が登場していないため、何を指しているのか分かりにくく感じます。

Copy link
Owner Author

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 = (

Choose a reason for hiding this comment

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

複数代入を行うより中間的な変数を設けるなどした方が読みやすいと感じました。
Pythonでは一般的でしたらすみません🙇

Copy link
Owner Author

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)

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)ではないでしょうか?

Choose a reason for hiding this comment

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

L33で配列をコピーしているのでO(N)ですね。

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)な計算量にしたいときはそれが律速になるので避けるが)。
Copy link

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倍速く、再帰などで繰り返し呼ばないならば大きな問題はないというのはそうでしょう。

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.

6 participants