回転ソートされた配列を検索 - バイナリ検索を

タイトル

アレイは、以前は未知点で回転させたに従って昇順と仮定する。

(例えば、アレイ  [0,1,2,4,5,6,7] になるかもしれ  [4,5,6,7,0,1,2] )。

標的配列、そのインデックスリターンの存在は、それ以外の場合は、返された場合、所定の目標値を検索します  -1 。

あなたは、配列要素が重複して存在しないと仮定することができます。

アルゴリズムのあなたの時間複雑でなければなりません  O(ログ  のN-)レベル。

例1:

入力:NUMS = [ 4567012 ]、目標= 0 
出力:4

例2:

【:入力NUMS = 4567012 ]、ターゲット= 3 
出力: - 1

 

思想

タイトルが必要  O(logN個)O L O G N この問題を決定することができる)の時間複雑度は、キーを分割する方法について、二分探索を使用する必要があります。

タイトルが言ったように、非繰り返しの数、例えば:

1,234,567は、大きく二つのカテゴリーに分けることができ、

第2345671これは、すなわち  nums[start] <= nums[mid]このケースはあります  2 <= 5

この場合、最初の半分が注文しました。もしそうなら  nums[start] <=target<nums[mid]、あなたは前半、後半はそう見つけることがわかります。

第二のカテゴリー、すなわち、例えば6712345  nums[start] > nums[mid]このケースはあります  6 > 2

この場合、第2の半分と秩序あります。もしそうなら  nums[mid] <target<=nums[end]、その後を探しに行く前後半、または半分に見えます。

少ないのはなぜ多くの人々が、お願いします。実際には、時間は、どのようにロジックとI試合を2つだけの数字を最後にあります。

 

コード

FUNC検索(_ NUMS:[INT]、_ターゲット:INT) - > のInt {
     もし nums.count <= 0 {
         リターン - 1
    }
    VAR開始 = 0 
    VAR端 = nums.count - 1つの
    VARの中間ます。int = 0 
    一方開始<= 終了{
        ミッド = +開始(終了-開始)/ 2 
        であれば NUMS [中間] == ターゲット{
             戻りミッド
        }
        場合 NUMSは、[開始] <= NUMS [中間] {
             場合、ターゲット> = NUMSは&&ターゲット<[開始] {NUMS [中間]を =ミッド- 1 
            } {
                開始 =ミッド+ 1
            }
        } {
             もしターゲット<= NUMS [END] &&ターゲット> NUMS [中間] {
                開始 =ミッド+ 1 
            } {
                終了 =中旬- 1
            }
        }
    }
    リターン - 1 
}

コピーしてあなたが成功することができ、上記のコードを貼り付けますが、このアルゴリズムは難しいことではありません、あまりにも多くの説明をしません!

おすすめ

転載: www.cnblogs.com/guohai-stronger/p/12056691.html