Skip to content

Conversation

@Fuminiton
Copy link
Owner

```python
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
maximum_subarray = -sys.maxsize - 1
Copy link

Choose a reason for hiding this comment

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

-sys.maxsize - 1はintの最小値ではなさそうです。

>>> -sys.maxsize -1
-9223372036854775808
>>> -sys.maxsize -2
-9223372036854775809

Copy link

Choose a reason for hiding this comment

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

IronPythonにはこんな説明がありました。

The largest positive integer supported by the platform’s Py_ssize_t type, and thus the maximum size lists, strings, dicts, and many other containers can have.
https://ironpython-test.readthedocs.io/en/latest/library/sys.html#sys.maxsize

Copy link
Owner Author

Choose a reason for hiding this comment

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

レビュー、実験、リンクの共有もいただきありがとうございます。

すると、maximum_subarrayの初期値は、
MIN_NUMS = -10001あたりを定義しておいて使うのが良さそうですかね。

Copy link

Choose a reason for hiding this comment

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

あー、そもそもの話として、maximum_subarray に負の小さい値を入れるというのが「番兵」であるという認識はありますか。つまり、

value_set = False
value = 0
for x in a:
    if not value_set:
        value = x
        value_set = True
    else:
        value = max(x, value)

を番兵使って、value の初期値を -inf などとしても状況によっては動くということです。

それで、入力への制約というのはだんだん守られなくなっていくものなので、番兵を使ってうまく書けないならば、使わないことも考えたほうがいいでしょう。
https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.jdtk9v35bca4

Copy link
Owner Author

Choose a reason for hiding this comment

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

レビューありがとうございます。

maximum_subarray に負の小さい値を入れるというのが「番兵」であるという認識はありますか。

はじめのループで更新される、maximum_subarrayとしては現状あり得ないだろう値くらいの認識で、番兵だとは気付けていなかったです。

それで、入力への制約というのはだんだん守られなくなっていくものなので、番兵を使ってうまく書けないならば、使わないことも考えたほうがいいでしょう。

はい。ご指摘のとおりで、制約が変わり得ることを念頭において、初めから nums[0]を初期値とする、フラグを用いて初めは特殊対応するなど検討すべきでした。

- 総当たり(累積和なし)
- 総当たり(累積和あり) <- 初見時、提出してTLEになった
- 分割統治は、並列処理が適切な場面では選択肢になるのだろうか
- kadaneは変数が減らせるくらいが嬉しさだろうと思うので、step1の実装の方がわかりやすくいい気がする
Copy link

Choose a reason for hiding this comment

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

空間計算量がO(1)にできるのは入力が大きい場合はメリットだと思います。

return left_max_sum + right_max_sum

return get_max_sum(0, len(nums))
``` No newline at end of file
Copy link

Choose a reason for hiding this comment

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

ただの感想なんですが、この問題の分割統治あまりきれいじゃない感じがしてしまいます。
centerをまたぐところ部分の計算が煩雑に感じます。

Copy link
Owner Author

Choose a reason for hiding this comment

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

ご意見ありがとうございます。
自分は、「centerを必ず使う累積和の最大を見つける」というのは自然な気がしましたが、
やはり左右の分割だけで済まないのはちょっと抵抗感ありました。

Copy link

Choose a reason for hiding this comment

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

左右の分割 + O(n) は、たとえば、最大の内点を含まない長方形などでたまに出てくる気がします。今回はどんぴしゃという感じはしないですね。
https://en.wikipedia.org/wiki/Largest_empty_rectangle

Copy link
Owner Author

Choose a reason for hiding this comment

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

面白い類題の共有ありがとうございます。

真ん中で平面を分割して左右で部分問題を解き、
中央を跨ぐ最大の空の矩形を見つけていくのですね。

確かにこのケースだと、左右の分割 + 中央を考慮した処理を使うのが自然な気がしました。

class Solution:
def maxSubArray(self, nums: List[int]) -> int:
max_sum = -sys.maxsize - 1
current_max_sum = -sys.maxsize - 1
Copy link

Choose a reason for hiding this comment

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

_so_far と最後につけて、「ここまでの」を意味する変数名にする方もいらっしゃるようです。

Copy link
Owner Author

Choose a reason for hiding this comment

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

共有ありがとうございます。
_so_far、応用範囲が広くてかなり使えそうです。

Comment on lines +54 to +65
step1の実装の`maximum_subarray`の更新部分`sum_prefix - minimum_sum_prefix`を式変形していくと、
`-> sum_prefix - min(prev_minimum_sum_prefix, prev_sum_prefix)`
`-> num + prev_sum_prefix - min(prev_minimum_sum_prefix, prev_sum_prefix)`
`-min(A, B) = max(-A, -B)`であることから、
`-> num + max(prev_sum_prefix - prev_minimum_sum_prefix, prev_sum_prefix - prev_sum_prefix)`
`-> num + max(prev_sum_prefix - prev_minimum_sum_prefix, 0)`
`num`を共通因子としてmaxの中に入れて、
`-> max(num, num + prev_sum_prefix - prev_minimum_sum_prefix)`
ここで、`prev_sum_prefix - prev_minimum_sum_prefix`は、
`sum_prefix - minimum_sum_prefix`の1つ前の結果だったということになるので、
`sum_prefix - minimum_sum_prefix`を`current_max_sum`とでもおいて、
`current_max_sum = max(num, num + current_max_sum)`を更新していけば良いという話。

Choose a reason for hiding this comment

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

一言で言うと、こういうことですね。
olsen-blue/Arai60#32 (comment)

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