在旋轉數組中搜索

原題

  Suppose a sorted array 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.算法

題目大意

 假設一個排序的數組以一個未知的的樞軸旋轉。(即,0 1 2 4 5 6 7可能成爲4 5 6 7 0 1 2)。
  給定一個目標值,在數組中搜尋。若是存在就返回其對應的下標,不然返回-1。
  假設數組中不存在重複值。 數組

解題思路

  先在數組中找到最小元素對應的下標,若是下標爲0說明整個數組是序的,若是不是說明數組被分紅兩個有序的區間,判斷要查找的元素是那一個有序區間中,而後進行查找。spa

代碼實現

算法實現類.net

public class Solution {
    public int search(int[] nums, int target) {

        if (nums != null && nums.length > 0) {

            // 找最小元素對應的下標
            int minIndex = searchMinIndex(nums, 0, nums.length - 1);

            // 整個數組全局有序
            if (minIndex == 0) {
                return binarySearch(nums, 0, nums.length - 1, target);
            } 
            // 有兩個局部有序區間,  如 4 5 6 7 8 9 0 1 2 3 
            else {
                // 恬好和後一個有序區間的最後一個元素相等,返回對應的下標
                if (nums[nums.length - 1] == target) {
                    return nums.length -1;
                } 
                // target可能在後一個有序區間中
                else if (nums[nums.length - 1] > target) {
                    return binarySearch(nums, minIndex, nums.length - 1, target);
                } 
                // target多是前一個有序區間中
                else {
                    return binarySearch(nums, 0, minIndex -1, target);
                }
            }
        }

        return -1;
    }

    /**
     * 二分搜索
     *
     * @param nums   數組
     * @param start  起始位置
     * @param end    結束位置
     * @param target 搜索目標
     * @return 匹配元素的下標
     */
    public int binarySearch(int[] nums, int start, int end, int target) {

        int mid;
        while (start <= end) {
            mid = start + ((end - start) >> 1);

            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] > target) {
                end = mid - 1;
            } else {
                start = mid + 1;
            }
        }

        return -1;
    }

    /**
     * 找最小元素的下標
     *
     * @param nums  數組
     * @param start 起始位置
     * @param end   結束位置
     * @return 最小元素的下標
     */
    public int searchMinIndex(int[] nums, int start, int end) {

        int mid;
        while (start < end) {
            mid = start + ((end - start) >> 1);
            // 後一個數比前個數小就找到了
            if (nums[mid] > nums[mid + 1]) {
                return mid + 1;
            }
            // 說明中間值在第一個有序的數組中
            else if (nums[mid] > nums[start]) {
                start = mid;
            }
            // 說明中間值在第二個有序的數組中
            else {
                end = mid;
            }
        }

        // 說明整個數組是有序的
        return 0;
    }
}
相關文章
相關標籤/搜索