Skip to content

35. Search Insert Position#39

Open
hemispherium wants to merge 1 commit into
mainfrom
0035-search-insert-position
Open

35. Search Insert Position#39
hemispherium wants to merge 1 commit into
mainfrom
0035-search-insert-position

Conversation

@hemispherium
Copy link
Copy Markdown
Owner

@hemispherium hemispherium self-assigned this May 1, 2026
int right = nums.size();

while (left < right) {
int mid = (left + right) / 2;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

オーバーフローを避けるため、

int mid = left + (right - left) / 2;

と書いたほうが良いと思います。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

承知しました。確かにそちらの方がよさそうです。


while (left < right) {
int mid = (left + right) / 2;
if (nums[mid] == target) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

念のため確認させてください。この if 文はなくても動きますか?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あまり深く考えていなかったのですが、二分探索が終わるとleftとrightの値が同じになるはずなのでこのif文は必要なかったと思います。一応LeetCodeでも確認したところなくても動きました。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

二分探索が終わるとleftとrightの値が同じになる

とありますが、ループ終了後には、どこを指していますか?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The 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のインデックスを指しそうです。
https://leetcode.com/playground/mR6MWyoh

また、下記のコードがあることで最終的な答えは変わらないですがnums[mid] == targetの場合は早期にループを抜けられることもわかりました。

if (nums[mid] == target) {
    return mid;
}

Comment on lines +4 to +7
auto it = find(nums.begin(), nums.end(), target);
if (it != nums.end()) {
return it - nums.begin();
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

問題文には、

You must write an algorithm with O(log n) runtime complexity.

とありますが、こちらの計算量はどうなっていますか?

lower_boundを一回呼び出すだけで書けますか?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5ky7さんのPRを参考にlower_bound1回だけで書いてみました。見つからない場合もitがnums.end()になるのでdistanceを取ればちょうどnums.size()と同じになるのでこれだけでよかったです。
https://github.com/5ky7/arai60/pull/41/changes#diff-0c860cd754249868513e4f9054206317fa33d0f548fc3896ac2b3e11822fd852R5

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;
    }
};

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ぼくの書いた方の計算量ですが、lower_boundの計算量はO(log n)ですがfindの方の計算量はO(n)のようなので問題文の条件をクリアできていなさそうです。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

見つからない場合もitがnums.end()になる

見つからない場合は、いつもそうなりますかね?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

見つからない場合というかtarget以上の要素がない場合、つまりtargetがいちばん後ろにくるべきケースではlower_boundでnums.end()が返ると思うのでこれでいいかなと思いました。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

「(target以上の要素が)見つからない」という意味でしたら、それで合っていますね。


### step2

他の方のコード(https://github.com/5ky7/arai60/pull/41/changes#diff-0c860cd754249868513e4f9054206317fa33d0f548fc3896ac2b3e11822fd852R19)を見てみると、lower_bound自体を実装していたので自分も実装してみた。
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

実装したlower_boundのコードもPRに含めると良いと思います。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

すみません、何か勘違いしているかもなのですがstep2に載せたコードがlower_boundの実装のつもりでした。

Copy link
Copy Markdown

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

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

承知しました。ありがとうございます!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants