問題のLeetcodeソリューション - バイナリサーチアルゴリズムのアイデア

1.処方要件

通常の実現

Input : [1,2,3,4,5]
key : 3
return the index : 2
公共INT binarySearch(INT [] NUMS、INTキー){ int型のL = 0、H = NUMS .LENGTH - 1。一方、(L <= H){ int型のm = 1 +(H - L)/ 2。(NUMS [m]の場合==キー){ 戻りM。} そうであれば(NUMS [M] >キー){H = M - 1。} 他{L = M + 1です。}} リターン- 1。}

時間複雑

また、バイナリサーチバイナリ検索として、それは間隔を半分に見えるたびに知られ、このバイナリ特性アルゴリズムの時間計算量はO(logN個)です。

計算メートル

mの値を計算する2つの方法があります。

  • M =(L + H)/ 2
  • M = 1 +(H - L)/ 2

L + hはオーバーフローが発生する可能性があり、追加、加算の即ち整数結果を表すことができる範囲よりも大きくなっています。しかし、L、hは正なので、時間 - lはオーバーフローの問題を追加しません。したがって、計算の第二の方法を用いることが好ましいです。

戻り値のために失敗した検索

それでもキーを見つけていない場合はループが終了すると、その後のルックアップに失敗した表現。2つの戻り値があります。

  • -1:エラーコードでキーが見つからないことを示し、
  • L:キーが正しい位置NUMSに挿入され

バリアント

バイナリ検索は、多くのバリエーションを持つことができ、変異体は、境界値を決定するために注意を払うを達成します。たとえば、次のようにキーの左端の位置を見つける達成するために要素を繰り返し配列です。

公共INT binarySearch(INT [] NUMS、INTキー){ int型のL = 0、H = NUMS .LENGTH - 1。(Lながら<H){ int型、M = Lの(H + - L)/ 2 IF(NUMS [M] > =キー){H = M。} 他{L = M + 1です。}} 戻りL。}

実装と、次の方法の適切な実現:

  • hが代入式H = Mであります
  • サイクリング条件は、L <Hました
  • 最後リットル代わりに返さ-1

NUMSの場合には[M]> =キー、キーが配置左端[L、M]閉区間で間隔、推定することができます。Hとすることができる溶液として代入式H = M、Mポジションです。

代入式のHは、H =ケースをmでループ条件はL <= hのであれば、その後の状況は、循環から撤退しないであろうだけ条件L <H下従って循環、表示されます。以下の場合は、場合= hの<サイクルを終了することができないサイクル条件Lを示しています。

nums = {0, 1, 2}, key = 1
l   m   h
0   1   2  nums[m] >= key
0   0   1  nums[m] < key
1   1   1  nums[m] >= key
1   1   1  nums[m] >= key
...

ループを抜けるには、キーが見つからないという意味ではありません場合は、最終的な結果が返されないはず-1。そこに見つからないことを確認するためには、コールの値が戻り位置とキー平等を終了するかを決定する必要があります。

1.処方要件

69. SQRT(x)は(簡単に)

入力:4 
出力:2 

入力:8 
出力:2 
説明:8の平方根は2.82842 ...であり、我々は整数を返すようにしたいため、小数部分は切り捨てられます。

〜X、及び満足SQRT == X / SQRT 0間のx特定の数を規定SQRT。バイナリサーチは、0〜xとの平方根を見つけるために使用することができます。

X = 8の場合は、その進化は... 2.82842である、それは最後の2ではなく3を返す必要があります。サイクリング条件は、L <= hとループが終了したときに、H lは常に1より小さい最後の戻り値がH、Lいけないので、それは、H = 2、L = 3です。

公共INT mySqrt(INT X){
     IF(X <= 1){ 戻りX。} int型のL = 1、H = X。(Lながら<= H){ int型ミッド= 1 +(H - L)/ 2。int型のSQRT = X /ミッド。(SQRT場合== MID){ 半ばを返します。} そうIF(中間> SQRT){H =ミッド- 1。} 他{L =ミッド+ 1。}} 戻りH; }

2.指定された要素は、最小の要素よりも大きいです

744ターゲット(簡単)より大きい最小の手紙を探します

入力:
文字= [ "C"、 "F"、 "J"] 
ターゲット= "D" 
出力: "F" 

入力:
文字= [ "C"、 "F"、 "J"] 
ターゲット= "K" 
を出力: "C"

トピック説明:与えられた文字と文字のターゲット文字の秩序配列は、ターゲットよりも最小の文字大きな文字を識別するように求め、そしてあなたは、文字のリターンを見つけることができない場合。

公共チャーnextGreatestLetter(CHAR []の文字、チャーターゲット){ int型のn =文字.LENGTH。int型のL = 0、H = N - 1。一方、(L <= H){ int型のm = 1 +(H - L)/ 2。(文字[M]であれば<=ターゲット){L = M + 1 } 他{H = M - 1。}} 戻りL <N 文字[L] 文字[ 0]。}

単一の要素の3秩序配列

ソートされた配列中の単一の要素540(中)

入力:[1、1、2、3、3、4、4、8、8] 
出力:2

件名の説明:注文した配列は、この番号を見つけるために、2回表示されません唯一の番号を持っています。

請求項(logN個)時間計算で解く、したがってXOR演算を解決するために、アレイを横切ることができないO、時間計算を行うことはO(N)です。

単一の要素の位置は、配列のインデックスを作成します。インデックス後、アレイ中に元々存在するペア状態が変更されます。mが偶数であり、そしてm + 1の場合<インデックス、次いでNUMS [M] == NUM​​S [M + 1]; M + 1> =索引は、次にNUMS [m]はNUMS [M + 1] =!

NUMS [M] == NUM​​S [M + 1]場合は、上記法則から知ることができ、次いで、配列インデックスの位置は、[M + 2、H]であるので、この場合L = M + 2; NUMS場合[M]! = NUM​​S [M + 1]は、インデックスは[L、M]、すなわちH = Mので、この時間である配列の位置。

代入式Hは、H = Mであるため、その後、唯一のループ条件L <Hにこのフォームを使用することができます。

公共INT singleNonDuplicate([] NUMSをINT){
     int型のL = 0、HはNUMSは= .LENGTH - 1; 一方(L <H){ int型M = Lの+(H - L)/ 2; IF(m個の2 == 1){M - ; //確保L / H / M間隔の大きさは常に奇数の外観になるように、少しでもある} (NUMS [M] IF == NUMS [Mの+ 1]){L = M + 2 ;} 他{H = M;}} }; NUMS [L]を返します

4.最初の間違ったバージョン

278ファーストバート・バージョン(簡単)

説明タイトル:与えられたN [1、2、...、N]バージョンを持つ要素を表すが、エラーを生じる、x位置の間違ったバージョンで表示されるようになった以降のバージョンです。エラーのバージョンは、最初のエラーが必要なバージョンを見つけるためにかどうかを知るためにisBadVersion(int型のX)を呼び出すことができます。

H = Mように、m番目のエラーのバージョンは、[L、M]との間の誤差の最初のバージョンを示す場合; [M + 1、H]の間の、さもなければ間違ったバージョンを、そのLよう= M + 1。

代入式のHので、H = Mであるので、ループ条件は、L <Hです。

公共INT firstBadVersion(INT N){
     int型のL = 1、H = N。(Lながら<H){ int型ミッド= 1 +(H - L)/ 2。IF(isBadVersion(MID)){H =ミッド。} 他{L =ミッド+ 1。}} 戻りL。}

アレイの回転の最小数

回転したソート配列における153検索最小(ミディアム)

入力:[3,4,5,1,2]、
出力:1
公共INT findMin(INT [] NUMS){
     int型のL = 0、H = NUMS .LENGTH - 1。(Lながら<H){ int型、M = Lの(H + - L)/ 2 (NUMS [M]であれば、<= NUMS [H]){H = M。} 他{L = M + 1です。}} 戻りNUMS [L]。}

間隔を6.検索

34.ソートされた配列に要素の最初と最後の位置を探します

入力:NUMS = [5,7,7,8,8,10]、目標= 8 
出力:[3,4] 

入力:NUMS = [5,7,7,8,8,10]、目標= 6 
出力[-1、-1]
公共のint []探索範囲(INT [] NUMS、INT対象){ int型最初= binarySearch(NUMS、ターゲット)INT最後= binarySearch(NUMS、ターゲット+ 1)- 1。(最初の場合== NUMSは.LENGTH || NUMSは、[最初] !=ターゲット){ 戻り新しいINT [] { - 1、- 1}。} 他{ 戻り新しいINT [] {まず、数学.MAX(最初、最後)}と、}} プライベートINT binarySearch(INT [] NUMS、INT対象){ int型のL = 0、H = NUMS.LENGTH; //注意時間的初始值一方(L <H){ int型のm = 1 +(H - L)/ 2。(NUMS [m]の場合> =ターゲット){H = M。} 他{L = M + 1です。}} 戻りL。}

おすすめ

転載: www.cnblogs.com/daimasanjiaomao/p/11009078.html