二分探索変形の検索回転ソート配列

タイトル:LeetCode(33)

昇順でソートされた配列が、事前に不明な特定のポイントで回転するとします。
(たとえば、配列[0,1,2,4,5,6,7]は[4,5,6,7,0,1,2]になる場合があります)。
指定されたターゲット値を検索します。ターゲット値が配列に存在する場合はそのインデックスを返し、そうでない場合は-1を返します。
配列に重複する要素はないと想定できます。
アルゴリズムの時間計算量はO(log n)レベルである必要があります。
例1:
入力:nums = [4,5,6,7,0,1,2]、ターゲット= 0
出力:4
例2:
入力:nums = [4,5,6,7,0,1,2 ]、ターゲット= 3
出力:-1

問題の解決策:問題
の意味は、回転配列で特定の値を検索できるようにすることです。存在する場合は、この値の対応する座標を返します。存在しない場合は、-1を直接返します。よく考えてみると、実際には二分探索の変形であることがわかります。二分探索を考えてみましょう。ただし、この質問の難しさは、元の配列がどこで回転されているかわからないことです。分析するタイトル。配列[01 2 4 5 6 7]には、次の7つの回転方法があります。

[0 1 2 4 5 6 7] 
[7 0 1 2 4 5 6] 
[6 7 0 1 2 4 5] 
[5 6 7 0 1 2 4] 
[4 5 6 7 0 1 2] 
[2 4 5 6 7 0 1] 
[1 2 4 5 6 7 0] 

観測結果:中央値が右端よりも大きい場合は左側が順番になり、中央値が右端よりも小さい場合は右側が順番になります。したがって、順序付けられた半分の最初と最後の2つの配列を使用して、ターゲット値がこの領域にあるかどうかを判断するだけで、どちらの半分を保持するかを判断できます。

int rotatedBinarySearch(int[] arr, int target){
    
    
 	// 最左侧元素下标
 	int left = 0;
 	// 最右侧元素下标
 	int right = arr.length - 1;
 	while(left <= right){
    
    
 	// 中间元素下标
 	int mid = left + (right - left) / 2;
 	if(arr[mid] == target){
    
    
 		return mid;
	 }
 
 // 情况1:如果中间元素在旋转点左侧
 	if(arr[mid] >= arr[left]){
    
    
 //target 如果位于中间元素的左侧
	 if(arr[mid] > target && target >= arr[left]){
    
    
 		right = mid - 1;
 	}else{
    
    
 	left = mid + 1;
 	      }
	 }
 // 情况2:中间元素在旋转点的右侧
 	else{
    
    
 // target 如果位于中间元素的右侧
	 if(arr[mid] < target && target <= arr[right]){
    
    
	 	left = mid + 1;
 	}else{
    
    
 		right = mid - 1;
 	     }
 	}
	 }
 	return -1; 
 	}

おすすめ

転載: blog.csdn.net/qq_43078445/article/details/106962381
おすすめ