1. 程式人生 > >LeetCode 33. Search in Rotated Sorted Array(旋轉有序陣列,查詢目標值Ⅰ)

LeetCode 33. Search in Rotated Sorted Array(旋轉有序陣列,查詢目標值Ⅰ)

題目描述:

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
    (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).
    You are given a target value to search. If found in the array return its index, otherwise return -1.
    You may assume no duplicate exists in the array.

分析:
    題意:給定一個旋轉有序非重複陣列,一個目標值,查詢該值。如果找到,返回對應座標,否則返回-1。
    思路:如果只是一個有序陣列,我們可以直接採用普通的二分法。可是現在經過旋轉操作,我們也需要對二分法做一些改進。假設陣列nums的大小為n,目標值為target,初始化指標left = 0,right = n - 1。
    ①計算mid = (left + right) >> 1(防止整型數計算溢位的寫法),若nums[left]、nums[right]或者nums[mid]等於target,則查詢完畢,直接返回對應座標
    ②我們可以看出,對於經過旋轉的陣列,總可以找到一個i,使得nums[i - 1] > nums[i](原始有序陣列除外),此時nums[0→i - 1]、nums[i→n - 1]各自為升序子陣列。那麼任意選擇一個j作為分割點,nums[0

→j - 1]、nums[jn - 1]至少有一段是升序的。根據這個性質,我們進行分類討論:Ⅰ. 如果nums[left] < nums[mid]且target值介於兩者之間,那麼需要在nums[left→mid - 1]中查詢,否則在nums[mid + 1→right]查詢。Ⅱ. 如果nums[mid] < nums[right]且target值介於兩者之間,那麼需要在nums[mid + 1→right]中查詢,否則在nums[left→mid - 1]查詢。
    時間複雜度為O(log(n))。

程式碼:

#include <bits/stdc++.h>

using namespace std;

// binary search
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int n = nums.size();
		// Exceptional Case: 
		if(n == 0){
			return -1;
		}
		int left = 0, right = n - 1;
		while(left <= right){
			int mid = (left + right) >> 1;
			// check left, mid, right
			if(nums[left] == target){
				return left;
			}
			if(nums[mid] == target){
				return mid;
			}
			if(nums[right] == target){
				return right;
			}
			if(nums[left] < nums[mid]){
				if(nums[left] < target && target < nums[mid]){
					right = mid - 1;
				}
				else{
					left = mid + 1;
				}
			}
			else{
				if(nums[mid] < target && target < nums[right]){
					left = mid + 1;
				}
				else{
					right = mid - 1;
				}
			}
		}
		return -1;
    }
};