-
Notifications
You must be signed in to change notification settings - Fork 0
35. Search Insert Position #39
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,11 @@ | ||
| ### step1 | ||
|
|
||
| findとlower_boundを使ってit != nums.end()のときはそのイテレータ、そうでない場合は配列のサイズを返すようにした。 | ||
|
|
||
| ### step2 | ||
|
|
||
| 他の方のコード(https://github.com/5ky7/arai60/pull/41/changes#diff-0c860cd754249868513e4f9054206317fa33d0f548fc3896ac2b3e11822fd852R19)を見てみると、lower_bound自体を実装していたので自分も実装してみた。 | ||
|
|
||
| ### step3 | ||
|
|
||
| step2を3回通すまで書き直し。 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| class Solution { | ||
| public: | ||
| int searchInsert(vector<int>& nums, int target) { | ||
| auto it = find(nums.begin(), nums.end(), target); | ||
| if (it != nums.end()) { | ||
| return it - nums.begin(); | ||
| } | ||
|
Comment on lines
+4
to
+7
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. 問題文には、
とありますが、こちらの計算量はどうなっていますか? lower_boundを一回呼び出すだけで書けますか?
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. 5ky7さんのPRを参考にlower_bound1回だけで書いてみました。見つからない場合もitがnums.end()になるのでdistanceを取ればちょうどnums.size()と同じになるのでこれだけでよかったです。 class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
auto it = lower_bound(nums.begin(), nums.end(), target);
int position = distance(nums.begin(), it);
return position;
}
};
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. ぼくの書いた方の計算量ですが、lower_boundの計算量はO(log n)ですがfindの方の計算量はO(n)のようなので問題文の条件をクリアできていなさそうです。 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.
見つからない場合は、いつもそうなりますかね?
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. 見つからない場合というかtarget以上の要素がない場合、つまりtargetがいちばん後ろにくるべきケースではlower_boundでnums.end()が返ると思うのでこれでいいかなと思いました。 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. 「(target以上の要素が)見つからない」という意味でしたら、それで合っていますね。 |
||
| auto it2 = lower_bound(nums.begin(), nums.end(), target); | ||
| if (it2 != nums.end()) { | ||
| return it2 - nums.begin(); | ||
| } | ||
| return nums.size(); | ||
| } | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| class Solution { | ||
| public: | ||
| int searchInsert(vector<int>& nums, int target) { | ||
| int left = 0; | ||
| int right = nums.size(); | ||
|
|
||
| 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. オーバーフローを避けるため、 int mid = left + (right - left) / 2;と書いたほうが良いと思います。
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. 承知しました。確かにそちらの方がよさそうです。 |
||
| if (nums[mid] == target) { | ||
|
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. 念のため確認させてください。この if 文はなくても動きますか?
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. あまり深く考えていなかったのですが、二分探索が終わるとleftとrightの値が同じになるはずなのでこのif文は必要なかったと思います。一応LeetCodeでも確認したところなくても動きました。 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.
とありますが、ループ終了後には、どこを指していますか?
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. 以下のプレイグラウンドで値を見ながら確認したのですが、nums[mid]がtarget以上の場合はright = midに、nums[mid]がtargetより小さい場合はleft = mid + 1になるので最終的にleftとrightは同じ値になって、target以上の最小のnumのインデックスを指しそうです。 また、下記のコードがあることで最終的な答えは変わらないですがnums[mid] == targetの場合は早期にループを抜けられることもわかりました。 |
||
| return mid; | ||
| } | ||
| 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,20 @@ | ||
| class Solution { | ||
| public: | ||
| int searchInsert(vector<int>& nums, int target) { | ||
| int left = 0; | ||
| int right = nums.size(); | ||
|
|
||
| while (left < right) { | ||
| int mid = (left + right) / 2; | ||
| if (nums[mid] == target) { | ||
| return mid; | ||
| } | ||
| if (nums[mid] < target) { | ||
| left = mid + 1; | ||
| } else { | ||
| right = mid; | ||
| } | ||
| } | ||
| return left; | ||
| } | ||
| }; |
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.
実装したlower_boundのコードもPRに含めると良いと思います。
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.
すみません、何か勘違いしているかもなのですがstep2に載せたコードがlower_boundの実装のつもりでした。
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.
lower_boundと振る舞いが違うので、ドキュメントを確認してみると良さそうです。
https://en.cppreference.com/cpp/algorithm/lower_bound
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.
承知しました。ありがとうございます!