-
Notifications
You must be signed in to change notification settings - Fork 0
035-search-insert-position #1
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,88 @@ | ||
| ## 問題文 | ||
| Given a sorted array of distinct integers and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. | ||
|
|
||
| You must write an algorithm with O(log n) runtime complexity. | ||
|
|
||
|
|
||
|
|
||
| Example 1: | ||
|
|
||
| Input: nums = [1,3,5,6], target = 5 | ||
| Output: 2 | ||
| Example 2: | ||
|
|
||
| Input: nums = [1,3,5,6], target = 2 | ||
| Output: 1 | ||
| Example 3: | ||
|
|
||
| Input: nums = [1,3,5,6], target = 7 | ||
| Output: 4 | ||
|
|
||
|
|
||
| Constraints: | ||
|
|
||
| 1 <= nums.length <= 104 | ||
| -104 <= nums[i] <= 104 | ||
| nums contains distinct values sorted in ascending order. | ||
| -104 <= target <= 104 | ||
|
|
||
| ## Step1で考えたこと | ||
| O(log n)という制約がある + 問題の特徴から -> Binary Search | ||
| Listを半分に分割し、右側の先頭の数字がTargetよりも大きければそのまま右側を走査、 | ||
| 小さければ左側を走査する | ||
| そのまま見つかればIndexをreturn | ||
|
|
||
| 見つからない場合、 | ||
|
|
||
| ## Step2での気づき | ||
| 解答解説を見た時、left, rightポインタを使えば良いのかと学んだ。 | ||
|
|
||
| Let's look at the case where the target number is not present. | ||
|
|
||
| Input: nums = [1,3,5,6], target = 2 | ||
| [1,3,5,6] | ||
| L M R | ||
| Now middle number is greater than the target, so move R to M - 1. | ||
|
|
||
| [1,3,5,6] | ||
| L | ||
| R | ||
| M | ||
| Now middle number is less than the target, so move L to M + 1. | ||
|
|
||
| [1,3,5,6] | ||
| R L | ||
| Now L is greater than R. We stop binary search. As a result, we don't find the target. | ||
|
|
||
| The description says "return the index where it would be if it were inserted in order." | ||
|
|
||
| In this case, we should insert the target into index 1. As you see, L is now at index 1, so | ||
|
|
||
| return 1 (= left index) | ||
|
|
||
| ### Points | ||
| Return left index if you don't find the target. | ||
| 見つからない場合のreturnするIndexの考え方も吸収できた。 | ||
|
|
||
| ### 間違えていたところとしては、 | ||
| 1. left <= rightとしていなかった。 | ||
| 2. right, leftの値更新の際の1ずらすところができていなかった。 | ||
|
|
||
| right = mid - 1, left = mid + 1としないと、left < rightという制約を超えることがないため無限ループを引き起こしてしまう。 | ||
|
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. こちらについても念のため質問させてください。
|
||
|
|
||
| ## GPTからもらった解答 | ||
|
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. https://nuc.hatenadiary.org/entry/2025/11/29/ の「二分探索を読めるか」の項も参考にされることをおすすめします。
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. こちら読ませていただきました。大変面白い内容なので他の項も含めて今後参考にさせていただきます。 |
||
| ``` | ||
| class Solution: | ||
| def searchInsert(self, nums: List[int], target: int) -> int: | ||
| left, right = 0, len(nums) # 右端は“外” | ||
| while left < right: | ||
| mid = (left + right) // 2 | ||
| if nums[mid] < target: | ||
| left = mid + 1 | ||
| else: | ||
| right = mid | ||
| return left # 最初に target 以上が出る位置 | ||
| ``` | ||
| target が配列内にあればその index、なければ挿入位置を返す | ||
| target > 最後の要素 の場合でも left == len(nums) になって正しく 末尾 を返す. | ||
| distinct でなくても“先頭の位置”が取れる(一般に強い) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| from typing import List | ||
|
|
||
| class Solution: | ||
| def searchInsert(self, nums: List[int], target: int) -> int: | ||
| mid = nums.len() / 2 | ||
| if target > List[mid]: | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # 答えを見てから自力で書いてみたコード | ||
| class Solution: | ||
| def searchInsert(self, nums: List[int], target: int) -> int: | ||
| left = 0 | ||
| right = len(nums) - 1 | ||
|
|
||
| while left < right: | ||
| mid = (left + right) // 2 | ||
|
|
||
| if target == nums[mid]: | ||
| return mid | ||
| elif target < nums[mid]: | ||
| right = mid | ||
| else: | ||
| left = mid | ||
|
|
||
| return left |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| class Solution: | ||
| def searchInsert(self, nums: List[int], target: int) -> int: | ||
| left = 0 | ||
| right = len(nums) - 1 | ||
|
|
||
| while left <= right: | ||
| mid = (left + right) // 2 | ||
|
|
||
| if nums[mid] == target: | ||
| return target | ||
| elif nums[mid] > target: | ||
| right = mid - 1 | ||
| else: | ||
| left = mid + 1 | ||
| 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.
念のため質問させてください。なぜ left <= right としないと意図しない挙動になるのか説明してみていただけますか?また、
それぞれ答えてみていただけますか?