Conversation
| int rightSum = Integer.MIN_VALUE; | ||
| int currentRightSum = 0; | ||
| for (int i = mid + 1; i <= right; i++) { | ||
| currentRightSum += nums[i]; | ||
| rightSum = Math.max(rightSum, currentRightSum); | ||
| } |
There was a problem hiding this comment.
mid == rightだとrightSumがInteger.MIN_VALUEになるなと思いましたが、rightが必ずmidより大きくなるようにmidを計算しているから上手くいくんですね。関数の頭に assert mid < right; みたいにアサーションを書いても良いのかもしれないなと思いました。
There was a problem hiding this comment.
確かに、閉区間でやっていて、maxSubArrayHelper は長さが1のときには early return しているので、左も右も大きさが1以上はある、というのを示さないとこのプログラムがきちんと動くことが分からないですね。
できるだけそういうことは読み手に証明させないように書きたいですね。
| class Solution { | ||
| public int maxSubArray(int[] nums) { | ||
| int maxSubArray = nums[0]; | ||
| int sumInWindow = 0; |
There was a problem hiding this comment.
Sliding Windowのwindowでしょうか?
自分がSliding Windowをよく理解していないからというのもございますが、何のsumなのかわかる変数名がいいかなと感じました。
There was a problem hiding this comment.
@Ryotaro25
すいません、返信大変遅くなりました。
はい、sliding window の window の意味でこの命名にしていました。しかしご存じない方が見ると意味が分かりづらいのはその通りだと思います。下の解法にあるような currentSum とかだと良いでしょうか?もっと良い案があったら教えていただけると嬉しいです🙏
There was a problem hiding this comment.
Window 単体でも A restricted range. という意味ですね。
https://en.wiktionary.org/wiki/window#Noun
ただ、それを認めたうえで、これ、日本語だと思うと、びっくりすると思うんですよ。
maxSubArray は、「部分配列の最大」ということですが、部分配列の和が最大なのは気合で読めたとしましょう。
次に、「限定された範囲の中の合計」が出てきて、限定された範囲というのはどこだ、となるでしょう。
そうすると、開始点と終了点を探すパズルが発生して、= 0 を代入した瞬間と、ループの num を足した瞬間であることが分かるのですが、このことについてのヒントが欲しいですね。
この変数が入っているのは「num を使う場合の部分配列の合計の最大」ですね。
で、これが分かると、ようやく帰納法を使って、「num の前までを使う場合の部分配列の合計の最大」が分かっているとして、「num を使う場合の部分配列の合計の最大」を計算するにはどうしたらいいのかを考えていると分かります。
GPT に聞いたところ、subArraySumSoFar, maxEndingHere, localMaxSubArraySum あたりをサジェストしてきました。
There was a problem hiding this comment.
次に、「限定された範囲の中の合計」が出てきて、限定された範囲というのはどこだ、となるでしょう。
そうすると、開始点と終了点を探すパズルが発生して、= 0 を代入した瞬間と、ループの num を足した瞬間であることが分かるのですが、このことについてのヒントが欲しいですね。この変数が入っているのは「num を使う場合の部分配列の合計の最大」ですね。
で、これが分かると、ようやく帰納法を使って、「num の前までを使う場合の部分配列の合計の最大」が分かっているとして、「num を使う場合の部分配列の合計の最大」を計算するにはどうしたらいいのかを考えていると分かります。
いやー仰るとおりですね。
GPT に聞いたところ、subArraySumSoFar, maxEndingHere, localMaxSubArraySum あたりをサジェストしてきました。
ありがとうございます。
どれも良いですが、subArraySumSoFar は特に納得感があります。認識に個人差はあると思いますが、so far と書いてあると「(開始点から) 現時点までの」というニュアンスを含まれる気がするので。
上記採用して Step 4 に記載しました。
|
|
||
| ### Cubic な解法 | ||
|
|
||
| タイムアウトするようなコードも書けるようになっておけばそこからより良い解法を考えられるようになる、とどこかで oda さんが仰ってたのを思い出して書いてみました。予想通り TLE。 |
There was a problem hiding this comment.
面白いですね。
”タイムアウトするようなコードも書けるようになる” → ”良い解法を考えられる”
こうなるために、意識することなどございますか?どこをさわればTLEになるのか把握するなどですかね。
There was a problem hiding this comment.
@Ryotaro25
こちらも大変返信遅くなりました。
個人的には、ひとまず手を動かすのが大事なのかなと考えています。頭の中をテキストエディタなりノートに書き出せば脳内メモリの節約 (というか拡張?) が出来て理解が進みますし、Leetcode のような判定ロジックを提供してくれるサービスに submit すれば実装の確認も出来るので、そういった作業をしていくと良い解法に近づいていけるのかなと思います。手を動かさずにただただ考え続けるよりもずっと効率が良く感じます。
https://leetcode.com/problems/maximum-subarray/description/