560.subarray sum equals k#16
Conversation
| sum += nums[i]; | ||
| if (sum == k) { | ||
| count++; | ||
| } |
There was a problem hiding this comment.
この部分は、下のループ内に入れられませんか?
sum += nums[i];
if (sum == k) {
count++;
}
There was a problem hiding this comment.
レビューありがとうございます。
空配列が来た場合に対応したつもりでしたがj=iから始めれば下のループに一元化できますね。
There was a problem hiding this comment.
空配列ならそもそも、外側のforループに入らず、また、これで空配列に対応する処理とはなっていないので、コードを追えていなさそうに感じました。
There was a problem hiding this comment.
ご返信ありがとうございます。
そうですね、おそらく空配列でなく最初の一つの要素がkだった場合を考えていました。
空配列はそもそもconstrainsで存在しないのですね。
| if (sum == k) { | ||
| count++; | ||
| } | ||
| for (int j = i + 1; j && j < nums.size(); j++) { |
There was a problem hiding this comment.
returnで謎の値が発生したのでjが配列外にアクセスする場合にやめるというのをlistnode的に手癖で書きましたが、初期化の際のスタック領域のごみが問題でした。
There was a problem hiding this comment.
j && j < nums.size()がどういう動きになるか説明できますか?
There was a problem hiding this comment.
cppだと0以外のすべての数が真になるので、常にtrueで無いのと同じですね。
配列が先に続いていないことが<nums.size()で表せていることがよくわかっていませんでした。
|
|
||
| 解答とコメント集みた。 | ||
| なるほど、記録しておくのは部分配列の中でもnumsの先頭からの要素が0個からN個に至るまでのN+1個でいいのか。 | ||
| で、それらの差集合を取ると[1,1,2,5]でk=7の時は[1,1,2,5]-[1,1]=[2,5]などを回収できるという。 |
There was a problem hiding this comment.
差集合はA=[1,1,2,3]としてB=[1,1]としてA-B=[2,3]を意図したかったのですがこのような表現・比喩は混乱を招くと思いますか。ご意見をお聞かせください。
There was a problem hiding this comment.
専門用語らしきものを別の意味で使うと通じないか、混乱させる表現になると思います。以前のPRの「樹形図」の話とも関連すると思います。
今回は、ある部分配列からそのプレフィックスを取り除くことを意味しますね。
There was a problem hiding this comment.
ありがとうございます。累積和をプレフィックスと言うのですね。知りませんでした。
なるべく専門用語に近い語彙は避けるようにします。
個人的にはより大きなプレフィックスからあるプレフィックスを取り除くというイメージです。
There was a problem hiding this comment.
累積和ではなく、先頭を含む部分配列のことをプレフィックスと呼んでいます。
| ## step2 | ||
|
|
||
| 解答とコメント集みた。 | ||
| なるほど、記録しておくのは部分配列の中でもnumsの先頭からの要素が0個からN個に至るまでのN+1個でいいのか。 |
There was a problem hiding this comment.
ここではNはO(N)にあたるnums.size()ですね。分かりづらかったです。
There was a problem hiding this comment.
「O(N)にあたる」はどういった意味合いでしょうか?O(N)の意味を理解しているのかが、気になりました。
O(N)は、N(ここではNをnums.size()と定義)に比例する数で抑えられるという意味ですね。
There was a problem hiding this comment.
ありがとうございます。
そうですね、他のコメントで仰っていただいたように現在地がインデックスiの時にインデックスが0からiの連続配列が空配列と0<=i<=nums.size()のnums.size()+1個になります。
O(N)と同じ用法でのNということでしたが、NはNの定数倍を省略しているのでnums.size()で書いたほうが正確でした。
There was a problem hiding this comment.
現在地がインデックスiの時にインデックスが0からiの連続配列が空配列と0<=i<=nums.size()のnums.size()+1個になります
「現在地がインデックスiの時」とiを固定しているように見えますが、プレフィックス(+空配列)の個数がnums.size()+1個と全体の話をしているので、意味が通らない文になっていると感じました。
| 2.numsの部分配列(連続した空でない部分。インデックス1,2はよいが1,3は連続してないのでダメ)の合計がkになるものの数を求めよ | ||
| というもの。ちなみにkは負の値もとる。 | ||
|
|
||
| 思いつかなかったのでO(N^2)であるブルートフォース(ヒント1を見た)を実行。 |
There was a problem hiding this comment.
全てのsubarrayを列挙して、それぞれsumを計算する方法は思いつきましたか?
There was a problem hiding this comment.
うーん、2^n個の配列の時点で諦めましたが計算量考えて実行してもよかったかもしれません。
There was a problem hiding this comment.
部分配列と言った時点で配列に存在しない並び(元の配列の奇数番目を飛ばした配列など)を選ぶことはないのでしょうか。
部分配列の個数はその場合N(N+1)/2になり、空配列を含むなら+1されますね。
There was a problem hiding this comment.
A subarray is a contiguous non-empty sequence of elements within an array.
と問題文にありますね。
| 解答とコメント集みた。 | ||
| なるほど、記録しておくのは部分配列の中でもnumsの先頭からの要素が0個からN個に至るまでのN+1個でいいのか。 | ||
| で、それらの差集合を取ると[1,1,2,5]でk=7の時は[1,1,2,5]-[1,1]=[2,5]などを回収できるという。 | ||
| 実際にはunordered_mapを使うので和の差をとり9-2=7とする。つまり今までの部分配列に2が存在したらカウントする。 |
There was a problem hiding this comment.
今までの部分配列に2が存在
「今までの部分配列」とは何を指しますか?また、「2が存在」とはどういう意味でしょうか?
There was a problem hiding this comment.
記述が独りよがりでしたが、和to配列個数を前提としているので和が2の今までに現れた配列の個数を見ます。1以上ならansにカウントするということです。
There was a problem hiding this comment.
正確には、「今までの部分配列」というのは、インデックスiを見ている時、インデックス0からi - 1を末尾とする、先頭を含む部分配列(プレフィックス)と空配列のことですね。
| 解答とコメント集みた。 | ||
| なるほど、記録しておくのは部分配列の中でもnumsの先頭からの要素が0個からN個に至るまでのN+1個でいいのか。 | ||
| で、それらの差集合を取ると[1,1,2,5]でk=7の時は[1,1,2,5]-[1,1]=[2,5]などを回収できるという。 | ||
| 実際にはunordered_mapを使うので和の差をとり9-2=7とする。つまり今までの部分配列に2が存在したらカウントする。 |
There was a problem hiding this comment.
unordered_mapを使うので和の差をとり9-2=7とする
「unordered_mapを使うので」と「和の差をとり」の繋がりが不明でした。unordered_mapには何が格納されていますか?
There was a problem hiding this comment.
和とその和になる配列の個数のmapですね。ここら辺step1と同じ温度で書くべきでした。
There was a problem hiding this comment.
論理的な繋がりが反対に見えて、正しく理解しているかどうかが気になりました。
合計がある数となるプレフィックスの個数を知りたいので、そのための道具として、unordered_mapを使うという流れだと思います。
There was a problem hiding this comment.
[1,1,2,5]-[1,1]=[2,5]という上の記述に対応して9-2=7という式が成り立ちますが、実際にはunordered_mapによって探したい合計値は2であるのでsum_to_count.contains(9-7)つまりsum_to_count.contains(sum-k)をするから9-2=7というより9-7=2がここで用いられる、という説明をするために
実際にはunordered_mapを使うので和の差をとり9-2=7とする
としましたが
unordered_mapを使うので実際には(9-7=2でなく)和の差をとり9-2=7とする
としたほうがよかったです。ご指摘ありがとうございます。
There was a problem hiding this comment.
あまり理解していなさそうに見えるので、見直してみた方が良いかもしれません。
This problem: https://leetcode.com/problems/subarray-sum-equals-k/description/
Next problem: https://leetcode.com/problems/number-of-islands/description/