35.Search Insert Position#14
Conversation
| if (nums.back() < target) return nums.size(); | ||
| int left = 0, right = nums.size() - 1; | ||
| while (left < right) { | ||
| int mid = (left + right) / 2; |
There was a problem hiding this comment.
今回の問題の制約では起こりえないですが、 left と right を足したときのオーバーフローを避けるため、
int mid = left + (right - left) / 2;
と書いたほうがよいかもしれません。
There was a problem hiding this comment.
こんな書き方もあるというのを共有しておきます。
middle := int(uint(left+right) >> 1)https://cs.opensource.google/go/go/+/refs/tags/go1.24.2:src/slices/sort.go;l=133
| // (最初の早期リターンで)バグってしまった。まだまだ書き慣れていないみたい | ||
| // 書いてみて思ったが条件式はnums[mid]>=targetの方が分かりやすいかもしれない | ||
| // <他の人のコードを読んでコメント> | ||
| // - なるほど…、right=nums.size()とすること(半開区間)で最初の早期リターンを |
There was a problem hiding this comment.
半開区間という語は、うーん、結構人によって意味が違い、理解が曖昧であることを押し隠すのに便利なので、どういう意味付けで書いたのかを書いたほうがいいように思いますね。
たとえば、理情の先輩方(同期同士)でもこんな感じです。
https://discord.com/channels/1084280443945353267/1231966485610758196/1350728552399765555
There was a problem hiding this comment.
なるほどです
というか僕のも今読み返してみるとどういう意図で半開区間と書いたのか分からなくなってしまっていました笑
今回の場合恐らく、TFに対する半開区間[L,R)ではなく、検証対象のウィンドウが半開区間[L,R)という意味で使っていますね
また同時に、TFが(L,R]の場合で使われることも分かりました。
ありがとうございます!
There was a problem hiding this comment.
念のため補足させてください。
[false, ..., false, true, ..., true] と [true, ..., true, false, ..., false] のどちらで考えるかと、 [left, right) と (left, right] のどちらで考えるかは独立した内容だと思います。自分の観測範囲ですと [false, ..., false, true, ..., true] で考え、半開区間といった場合に [left, right) で考える人が多いように見えます。
「検証対象のウィンドウが半開区間 [L,R) 」は、探したい要素を含む区間を半開区間 [left, right) で表現する、ということでしょうか?もしそうであれば、自分にとってはそちらのほうが自然に感じられます。
There was a problem hiding this comment.
紛らわしくて申し訳ございません、「TFに対する半開区間[L,R)」というのは、(こういう書き方があるか分かりませんが(無い気がしてきましたが))TFに対する閉区間[L,R]に対する表現(全部Tか全部F)として用いました。今回の僕のコードは「TFに対する半開区間[L,R)」であり、「検証対象のウィンドウも半開区間[L,R)」になっていますね。
TF/FTと、[L,R)/(L,R]が別というのは分かっています。
「検証対象のウィンドウが半開区間
[L,R)」は、探したい要素を含む区間を半開区間[left, right)で表現する、ということでしょうか?もしそうであれば、自分にとってはそちらのほうが自然に感じられます。
そういう意味になります。ただ、検証対象のウィンドウに関しては全区間[L,R]の場合もある認識ですが、そちらはあまりプロダクションコードでは一般的ではないのでしょうか?
僕は問題の意味に応じて使い分ければよいのかと思っていました。
すみません、僕はもしかしたらnodchipさんのコメントの意味があまりよくわかっていなかったかもしれませんが、「TFに対する半開区間[L,R)」というのが変な表現ということでしょうか?
確かに「TFに対する全区間[L,R]」は存在しない気がしてきたのでおかしな表現だったかもしれません。
(left=mid+1で更新するので実質leftがT/Fになることが許可されているとしてもです)
There was a problem hiding this comment.
一番典型的には、開区間というのは実数について述べるものです。
開集合、閉集合は、位相空間論においても基本的な概念で、実数において開区間全体は開基です。
つまり、開集合と閉集合は性質として大きく異なるものです。
しかしながら、配列の話をするときには、整数という離散量なので、大した意味がないというのが一番初めの前提です。
その結果、何かの条件である a <= x < b の不等号に = がついているか、という程度の意味で使われています。
それで、私がここで問題にしたいのは、left から right の開区間などといったときに、「何が」その開区間の中に入っているのか、です。
insert_position ならば、答えは、0 <= position <= nums.size() ですよね。
だから、これは閉区間といえば閉区間なのです。つまり、「何が」を分かっていないで、開区間で閉区間でと書いても仕方がないでしょう。
There was a problem hiding this comment.
すみません、僕はもしかしたらnodchipさんのコメントの意味があまりよくわかっていなかったかもしれませんが、「TFに対する半開区間[L,R)」というのが変な表現ということでしょうか?
確かに「TFに対する全区間[L,R]」は存在しない気がしてきたのでおかしな表現だったかもしれません。
(left=mid+1で更新するので実質leftがT/Fになることが許可されているとしてもです)
「TFに対する半開区間[L,R)」という表現をあまり見ないように思いました。「[true, ..., true, false, ..., false] という配列について考える。この配列上の [L, R) という半開区間について考える。」という意味で合っていますでしょうか?もし違っているとするならば、この表現だと意味を誤解するという人がいるということになると思います。
[true, ..., true, false, ..., false] という配列を「TF」と略すと、伝わらない人がいそうな気がします。「[true, ..., true, false, ..., false] という配列」と書き下したほうが伝わりやすいように思いました。
問題
https://leetcode.com/problems/search-insert-position/description/
補足
<番号>r.cppは<番号>.cppを書きなおしたものになっています。(微妙に違うか同じです)