Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions 035-search-insert-position/memo.md
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としていなかった。
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 としないと意図しない挙動になるのか説明してみていただけますか?また、

  • left より左側の要素にはどのような特徴があるか?
  • left の位置の要素にはどのような特徴があるか?
  • left < x < right の x の位置の要素にはどのような特徴があるか?
  • right の位置の要素にはどのような特徴があるか?
  • right より右側の要素にはどのような特徴があるか?

それぞれ答えてみていただけますか?

2. right, leftの値更新の際の1ずらすところができていなかった。

right = mid - 1, left = mid + 1としないと、left < rightという制約を超えることがないため無限ループを引き起こしてしまう。
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

こちらについても念のため質問させてください。

  • なぜ right = mid となっているところ right = mid - 1 としても正しい答えが返って来ますか?
  • 同様に left = mid となっているところを left = mid + 1 としても正しい答えが返って来ますか?
  • right や left を動かし過ぎて、答えとなるインデックスを通り過ぎてしまうことはありませんか?


## GPTからもらった解答
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

https://nuc.hatenadiary.org/entry/2025/11/29/ の「二分探索を読めるか」の項も参考にされることをおすすめします。

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.

こちら読ませていただきました。大変面白い内容なので他の項も含めて今後参考にさせていただきます。

```
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 でなくても“先頭の位置”が取れる(一般に強い)
7 changes: 7 additions & 0 deletions 035-search-insert-position/step1.py
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]:

17 changes: 17 additions & 0 deletions 035-search-insert-position/step2.py
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
15 changes: 15 additions & 0 deletions 035-search-insert-position/step3.py
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