总结一下Rotated Sorted Array里找minimum或specific value

首先是找某一个值 target,并且数组里没有重复元素。

找法是:如果 mid <= high 并且 mid < target <= high那么mid到high之间的元素一定还是有序的,而且target在下半里,所以low = mid + 1。如果target < mid 那么high = mid - 1

              如果 mid >= low 那么上半一定是排好序的,如果 low <= target < mid,则high = mid - 1,否则low = mid + 1。

class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        low, high = 0, len(nums) - 1
        while low <= high:
            mid = (low + high) / 2
            if nums[mid] == target:
                return mid
            if nums[mid] <= nums[high]:
                if target > nums[mid] and target <= nums[high]:
                    low = mid + 1
                else:
                    high = mid - 1
            elif nums[mid] >= nums[low]:
                if target >= nums[low] and target < nums[mid]:
                    high = mid - 1
                else:
                    low = mid + 1
        return -1
                

其次在有重复元素的数组里找target。

有可能出现 333123 或 00110的情况所以必须保证 mid < high或者mid > low才满足部分有序,而当这俩条件都不满足的时候,如果low == mid, low = low + 1, 如果 high == mid, high = high - 1。

class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: bool
        """
        low, high = 0, len(nums) - 1
        while low <= high:
            mid = (low + high) / 2
            if nums[mid] == target:
                return True
            if nums[mid] < nums[high]:
                if target > nums[mid] and target <= nums[high]:
                    low = mid + 1
                else:
                    high = mid - 1
            elif nums[mid] > nums[low]:
                if target >= nums[low] and target < nums[mid]:
                    high = mid - 1
                else:
                    low = mid + 1
            elif nums[mid] == nums[high]:
                high -= 1
            else:
                low += 1
        return False

接下来是在无重复元素的数组里找最小值。如果mid < high,那么如果当前元素不是最小,最小值一定在前半,如果mid < low, 那么最小值一定也在前半,否则最小值在后半。

import sys

class Solution(object):
    def findMin(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        minimum = sys.maxint
        low, high = 0, len(nums) - 1
        while low <= high:
            mid = (low + high) / 2
            if nums[mid] < minimum:
                minimum = nums[mid]
            if nums[mid] < nums[high]:
                high = mid - 1
            elif nums[mid] < nums[low]:
                high = mid - 1
            else:
                low = mid + 1
        return minimum

最后是在有重复元素的数组里找最小值。此时分mid < high, mid > high, mid == high三种情况。

mid < high,如果mid不是最小值,那么最小值一定在前半,

mid > high,最小值一定在后半,

mid  == high, 如果mid == low,那么low += 1,因为最小值可以可以在前半也可以在后半。如果mid != low:如果mid不是最小值,那么最小值一定在前半。

class Solution(object):
    def findMin(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        minimum = sys.maxint
        low, high = 0, len(nums) - 1
        while low <= high:
            mid = (low + high) / 2
            if nums[mid] < minimum:
                minimum = nums[mid]
            if nums[mid] < nums[high]:
                high = mid - 1
            elif nums[mid] > nums[high]:
                low = mid + 1
            else:
                if nums[mid] < nums[low] or nums[mid] > nums[low]:
                    high = mid - 1
                else:
                    low += 1
                    
        return minimum


你可能感兴趣的:(Algorithm,LeetCode,面试题)