-
Notifications
You must be signed in to change notification settings - Fork 0
53. Maximum Subarray #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
for i in range(1, len(nums)): | ||
if max_subarray_using_the_index_as_tail[i - 1] <= 0: | ||
max_subarray_using_the_index_as_tail[i] = nums[i] | ||
continue |
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.
if max_subarray_using_the_index_as_tail[i - 1] <= 0:
max_subarray_using_the_index_as_tail[i] = nums[i]
else
max_subarray_using_the_index_as_tail[i] = max_subarray_using_the_index_as_tail[i - 1] + nums[i]
としたほうが、 True 時と False 時の対称性が見た目にはっきりわかり、分かりやすくなると思います。
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パターンをまだうまく使い分けれていない気がします。小田さんは結構下の書き方の方が好みなイメージがあります。今回はB,Cともに短いですし、if-elseの方が2つの条件の対比がはっきりして分かりやすくなるということは理解はできます。
パターン1
if A:
B
else:
C
パターン2
if A
B
continue
C
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.
はい、まあ、好みですが、
偶数ならA
奇数ならBこれは、if-else でいいでしょう。
if A:
B
continue
Cにしたいのは、C が長いとき、あと、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.
こういうのは趣味なのですが、基本的に「ある幅を持った選択肢を考えた上で気に入ったものを選んでいる」というプロセスが大事です。
ここで、書いた最終出力結果でしか評価されないと思っていると、だいぶそれは違います。要するに、「A と B と C を考慮した上で、A を選んだ」というのと「A で動くことが分かったので A にした」というのだと結果が同じでもまったく違う評価になるということです。
「B のほうが好みなんだけど」といわれたとしても「A と B と C を考慮した上で、A を選んだ、その理由はこういうものであるが、B もこういう理由でいいところがある、もしも B にして欲しいならばしましょうか」くらいの返答が求められています。
このあたりですかね。いや、結局 if-continue か、if-else かは好みの問題が多分にあるのですが、たとえば、2でも3でも5でも割り切れない数を集めろといわれたときに、
filtered = []
for number in numbers:
if number % 2 == 0:
pass
else:
if number % 3 != 0:
if number % 5 == 0:
continue
filtered.append(number)
など極めて多彩な選択肢があるわけで、選択肢のうち、どれを自発的に選択したかを意識して選択しているのが大事であるという感覚です。
prefix_sums[i + 1] = prefix_sums[i] + nums[i] | ||
|
||
def find_max_subarray(left, right): | ||
if not (left <= right): |
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.
if left > right:
でよいと思います。
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次元配列の添字が超えていないかの判定だとnot (0<= row < height)
と書く方がrow < 0 and row >= height
と書くより分かりやすいというコメントを以前貰ったことがあり、今回もそれに準拠してnot (正常なケース)
で書きました。
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.
だいたいの場合、a < b と右が大きくなるように並べたいんですよ。
なので、
not (a < b) のときに、a >= b と書くと、大きくない場合のことを言っているんだろうなと感じます。
Python は不等号がチェインできるので、not(a < b < c) は a >= b or b >= c より分かりやすいんじゃないでしょうか。
2分探索でも、なんでもいいですが、引数や変数は begin, end と並べたいですね。
left, right でもいいですが。
区間は [left, right) としましょう。そうすると、正常なときには
left <= middle < right です。
ただ、
left >= right
となったら、もう候補がありません。
ここで、
right <= left とかされると混乱します。
if not (left <= right): | ||
return -inf | ||
mid = (left + right) // 2 | ||
best_left_sum = 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_sum_in_left
あたりのほうが自然に感じますが、人によって感じ方が違うかもしれません。
best_left_sum = max(best_left_sum, prefix_sums[mid] - prefix_sums[i]) | ||
for i in range(mid, right + 1): | ||
best_right_sum = max(best_right_sum, prefix_sums[i + 1] - prefix_sums[mid + 1]) | ||
use_mid = best_left_sum + nums[mid] + best_right_sum |
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.
変数名が動詞から始まっている点に違和感を覚えました。 only と対比するのであれば with_mid
あたりがよいでしょうか…。
best_left_sum = max(best_left_sum, prefix_sums[mid] - prefix_sums[i]) | ||
for i in range(mid, right + 1): | ||
best_right_sum = max(best_right_sum, prefix_sums[i + 1] - prefix_sums[mid + 1]) | ||
use_mid = best_left_sum + nums[mid] + best_right_sum |
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.
use_midの処理を関数化しても良いと思いました。
https://leetcode.com/problems/maximum-subarray/