Files
hello-algo/ja/docs/chapter_searching/binary_search_edge.md
Ikko Eltociear Ashimine 954c45864b docs: add Japanese translate documents (#1812)
* docs: add Japanese documents (`ja/docs`)

* docs: add Japanese documents (`ja/codes`)

* docs: add Japanese documents

* Remove pythontutor blocks in ja/

* Add an empty at the end of each markdown file.

* Add the missing figures (use the English version temporarily).

* Add index.md for Japanese version.

* Add index.html for Japanese version.

* Add missing index.assets

* Fix backtracking_algorithm.md for Japanese version.

* Add avatar_eltociear.jpg. Fix image links on the Japanese landing page.

* Add the Japanese banner.

---------

Co-authored-by: krahets <krahets@163.com>
2025-10-17 05:04:43 +08:00

3.7 KiB
Raw Blame History

二分探索の境界

左境界を見つける

!!! question

重複要素を含む可能性がある長さ$n$のソート済み配列`nums`が与えられ、最も左の要素`target`のインデックスを返してください。要素が配列に存在しない場合は、$-1$を返してください。

挿入位置の二分探索方法を思い出すと、探索完了後、インデックス$i$はtargetの最も左の出現を指します。したがって、挿入位置の探索は本質的に最も左のtargetのインデックスを見つけることと同じです

挿入位置を見つける関数を使用してtargetの左境界を見つけることができます。配列にtargetが含まれていない可能性があることに注意してください。これは以下の2つの結果につながる可能性があります

  • 挿入位置のインデックス$i$が範囲外です。
  • 要素nums[i]targetと等しくありません。

これらの場合、単に$-1$を返します。コードは以下の通りです:

[file]{binary_search_edge}-[class]{}-[func]{binary_search_left_edge}

右境界を見つける

targetの最も右の出現をどのように見つけるでしょうか?最も直接的な方法は、nums[m] == targetの場合に探索境界を調整する方法を変更して、従来の二分探索ロジックを修正することです。コードはここでは省略されています。興味がある場合は、自分でコードを実装してみてください。

以下では、さらに2つの巧妙な方法を紹介します。

左境界探索を再利用する

targetの最も右の出現を見つけるには、最も左のtargetを見つけるために使用された関数を再利用できます。具体的には、最も右のターゲットの探索を最も左のターゲット + 1の探索に変換します。

下図に示すように、探索完了後、ポインタ$i$は最も左のtarget + 1(存在する場合)を指し、ポインタ$j$はtargetの最も右の出現を指します。したがって、$j$を返すことで右境界が得られます。

Transforming the search for the right boundary into the search for the left boundary

返される挿入位置は$i$であることに注意してください。したがって、$j$を得るためには1を引く必要があります

[file]{binary_search_edge}-[class]{}-[func]{binary_search_right_edge}

要素探索に変換する

配列にtargetが含まれていない場合、$i$と$j$は最終的にtargetより大きい最初の要素と小さい最初の要素をそれぞれ指します。

したがって、下図に示すように、配列に存在しない要素を構築して、左と右の境界を探索できます。

  • 最も左のtargetを見つけるには:target - 0.5を探索することに変換でき、ポインタ$i$を返します。
  • 最も右のtargetを見つけるには:target + 0.5を探索することに変換でき、ポインタ$j$を返します。

Transforming the search for boundaries into the search for an element

コードはここでは省略されていますが、このアプローチについて注意すべき2つの重要な点があります。

  • 与えられた配列numsには小数が含まれていないため、等しい場合の処理は心配ありません。
  • ただし、このアプローチで小数を導入するには、target変数を浮動小数点型に変更する必要がありますPythonでは変更は不要です