[LeetCode 題解] Search in Rotated Sorted Array

前言

【LeetCode 題解】系列傳送門:
http://www.cnblogs.com/double-win/category/573499.htmlhtml

題目描述

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.python

(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.code

You may assume no duplicate exists in the array.htm

題意

假設有一個有序的循環數組, 其起始位置未知。
如 序列0 1 2 4 5 6 7 可能的數組形式爲 4 5 6 7 0 1 2blog

給定一個目標數據,查找該數據是否在給定的數組中出現。 若是在數組中找到該目標數據,則返回該目標數據所在的數組下標, 不然返回-1.ip

Tips: 假設給定的數組中沒有重複的元素get

思路

根據題意提取關鍵信息: 在一個sorted array中查找給定元素
首先可以想到的是binary search。 因爲數組是一個循環數組, 那麼數組的最小值和最大值並不必定分別在數組兩端。
(1) 思路一: 從頭至尾,依次遍歷數組, 查找目標元素, 其時間複雜度O(n)
(2) 思路二: 從頭至尾尋找min, max, 而後將左側較大的數據concat到右側, 而後再用binary search。 時間複雜度 O(n/2) + O(logn) ~ O(n)
(3) 思路三:若是將原始數組分割成左右兩半, 能夠發現其具備以下幾種情形:博客

case 1: 最小值和最大值分別在左右兩側:
leftpart: [0 1 2 4] rightpart:[5 6 7]
值得注意的是該狀況最大值只能在最右側, 且最小值只能在最左側it

case 2:
最大值和最小值同側: 最大值在右側
leftpart: [ 2 4 5 6] rightpart: [7 0 1]
能夠發現 leftValue = 2 medianValue = 6 rightValue = 1
medianValue > leftValue && medianValue > rightValue:
若是 target > medianValue 或者 target < rightValue, 那麼必在rightpart
不然,必在leftpart

case 3:
最大值和最小值同側: 最小值在左側
leftpart: [6 7 0 1] rightpart: [2 4 5]
能夠發現 leftValue = 6 medianValue = 1 rightValue = 5
medianValue < leftValue && medianValue < rightValue:
若是 target < medianValue 或者 target > rightValue, 那麼必在leftpart
不然,必在rightpart

加上一些邊界條件,即得結果。

解法

class Solution(object):
    def findTarget(self, nums, minIndex, maxIndex, target):
        """
        :type nums: List[index]
        :type minIndex: int 
        :type maxIndex: int
        :type target: int
        :rtype: int
        """
        if nums[minIndex] == target:
            return minIndex
        if nums[maxIndex] == target:
            return maxIndex

        if maxIndex == minIndex:
            return 0  if target == nums[minIndex] else -1

        median = (minIndex + maxIndex) / 2
        if nums[median] == target:
            return median

        if nums[median] > nums[minIndex] and nums[median] > nums[maxIndex]:
            # maxValue and minValue is in right part
            if target > nums[median] or target < nums[minIndex]:
                return self.findTarget(nums, median + 1, maxIndex, target)
            else:
                return self.findTarget(nums, minIndex, median, target)
        elif nums[median] < nums[minIndex] and nums[median] < nums[maxIndex]:
            # maxValue is in left part
            if target < nums[median] or target > nums[maxIndex]:
                return self.findTarget(nums, minIndex, median, target)
            else:
                return self.findTarget(nums, median + 1, maxIndex, target)
        else:
            # maxValue is in maxIndex and minValue is in minIndex
            if target < nums[minIndex] or target > nums[maxIndex]:
                return -1
            elif target > nums[median]:
                return self.findTarget(nums, median + 1, maxIndex, target)
            else:
                return self.findTarget(nums, minIndex, median, target)

        
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        numSize = len(nums)
        # the array is empty
        if numSize == 0:
            return -1
        minIndex = 0
        maxIndex = numSize - 1
        return self.findTarget(nums, minIndex, maxIndex, target)

聲明

做者 Double_Win
出處 http://www.cnblogs.com/double-win/p/7966913.html
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文連接,不然做者保留追究法律責任的權利。 若本文對你有所幫助,您的關注和推薦是咱們分享知識的動力!
相關文章
相關標籤/搜索