-
Notifications
You must be signed in to change notification settings - Fork 0
35.Search Insert Position #14
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?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| #if __has_include("../../debug.hpp") | ||
| #include "../../debug.hpp" | ||
| #endif | ||
| // ここまでローカルでのデバッグ用なので気にしないでください -------------------- | ||
|
|
||
| #include <vector> | ||
|
|
||
| using namespace std; | ||
|
|
||
| // <時間> | ||
| // 6分 | ||
| // <感想> | ||
| // 直前に他の2分探索の問題を解いていたのですぐ解けるかと思っていたら | ||
| // (最初の早期リターンで)バグってしまった。まだまだ書き慣れていないみたい | ||
| // 書いてみて思ったが条件式はnums[mid]>=targetの方が分かりやすいかもしれない | ||
| // <他の人のコードを読んでコメント> | ||
| // - なるほど…、right=nums.size()とすること(半開区間)で最初の早期リターンを | ||
| // しなくてよくなるのか。色んなパターンがあるなあ。 | ||
| class Solution { | ||
| public: | ||
| int searchInsert(vector<int>& nums, int target) { | ||
| 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. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 今回の問題の制約では起こりえないですが、 left と right を足したときのオーバーフローを避けるため、
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. なるほどです。ありがとうございます! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. こんな書き方もあるというのを共有しておきます。 middle := int(uint(left+right) >> 1)https://cs.opensource.google/go/go/+/refs/tags/go1.24.2:src/slices/sort.go;l=133
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @hroc135 なるほどです。ありがとうございます! |
||
| if (nums[mid] < target) { | ||
| left = mid + 1; | ||
| } else { | ||
| right = mid; | ||
| } | ||
| } | ||
| return left; | ||
| } | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| #if __has_include("../../debug.hpp") | ||
| #include "../../debug.hpp" | ||
| #endif | ||
| // ここまでローカルでのデバッグ用なので気にしないでください -------------------- | ||
|
|
||
| #include <vector> | ||
|
|
||
| using namespace std; | ||
|
|
||
| // <時間> | ||
| // 1分 | ||
| // <感想> | ||
| // 半開区間を意識したので条件式はnums[mid]<targetとした | ||
| class Solution { | ||
| public: | ||
| int searchInsert(vector<int>& nums, int target) { | ||
| int left = 0, right = nums.size(); | ||
| while (left < right) { | ||
| int mid = (left + right) / 2; | ||
| if (nums[mid] < target) { | ||
| left = mid + 1; | ||
| } else { | ||
| right = mid; | ||
| } | ||
| } | ||
| return right; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # 35.Search-Insert-Position | ||
|
|
||
| <https://leetcode.com/problems/search-insert-position/description/> |
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.
半開区間という語は、うーん、結構人によって意味が違い、理解が曖昧であることを押し隠すのに便利なので、どういう意味付けで書いたのかを書いたほうがいいように思いますね。
たとえば、理情の先輩方(同期同士)でもこんな感じです。
https://discord.com/channels/1084280443945353267/1231966485610758196/1350728552399765555
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.
なるほどです
というか僕のも今読み返してみるとどういう意図で半開区間と書いたのか分からなくなってしまっていました笑
今回の場合恐らく、TFに対する半開区間
[L,R)ではなく、検証対象のウィンドウが半開区間[L,R)という意味で使っていますねまた同時に、TFが
(L,R]の場合で使われることも分かりました。ありがとうございます!
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.
念のため補足させてください。
[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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
紛らわしくて申し訳ございません、「TFに対する半開区間
[L,R)」というのは、(こういう書き方があるか分かりませんが(無い気がしてきましたが))TFに対する閉区間[L,R]に対する表現(全部Tか全部F)として用いました。今回の僕のコードは「TFに対する半開区間[L,R)」であり、「検証対象のウィンドウも半開区間[L,R)」になっていますね。TF/FTと、
[L,R)/(L,R]が別というのは分かっています。そういう意味になります。ただ、検証対象のウィンドウに関しては全区間
[L,R]の場合もある認識ですが、そちらはあまりプロダクションコードでは一般的ではないのでしょうか?僕は問題の意味に応じて使い分ければよいのかと思っていました。
すみません、僕はもしかしたらnodchipさんのコメントの意味があまりよくわかっていなかったかもしれませんが、「TFに対する半開区間
[L,R)」というのが変な表現ということでしょうか?確かに「TFに対する全区間
[L,R]」は存在しない気がしてきたのでおかしな表現だったかもしれません。(
left=mid+1で更新するので実質leftがT/Fになることが許可されているとしてもです)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 <= x < b の不等号に = がついているか、という程度の意味で使われています。
それで、私がここで問題にしたいのは、left から right の開区間などといったときに、「何が」その開区間の中に入っているのか、です。
insert_position ならば、答えは、0 <= position <= nums.size() ですよね。
だから、これは閉区間といえば閉区間なのです。つまり、「何が」を分かっていないで、開区間で閉区間でと書いても仕方がないでしょう。
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.
「TFに対する半開区間[L,R)」という表現をあまり見ないように思いました。「[true, ..., true, false, ..., false] という配列について考える。この配列上の [L, R) という半開区間について考える。」という意味で合っていますでしょうか?もし違っているとするならば、この表現だと意味を誤解するという人がいるということになると思います。
[true, ..., true, false, ..., false] という配列を「TF」と略すと、伝わらない人がいそうな気がします。「[true, ..., true, false, ..., false] という配列」と書き下したほうが伝わりやすいように思いました。