二分专题2 - leetcode153. Find Minimum in RotatedSorted Array/34. Find First and Last Position of Element

153. Find Minimum in Rotated Sorted Array

题目描述

假设按照升序排序的数组,在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

请找出其中最小的元素。(假设数组中不存在重复元素)

例子

Example 1:
Input: [3,4,5,1,2]
Output: 1

Example 2:
Input: [4,5,6,7,0,1,2]
Output: 0

思想
若旋转了,则num[l] > num[r];否则未旋转,直接返回num[l]。

当nums[mid] > nums[r]时,mid在未旋转部分,取l = mid + 1;
否则,mid在旋转部分,取r = mid;

解法

class Solution(object):
    def findMin(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        l, r = 0, len(nums)-1
        while l < r and nums[l] > nums[r]:
            mid = (l + r) >> 1
            if nums[mid] > nums[r]:    # 肯定未旋转,取左侧
                l = mid + 1
            else:    # 肯定旋转了,取右侧
                r = mid
        return nums[l]

34. Find First and Last Position of Element in Sorted Array

题目描述

给定一个按照升序排列的整数数组 nums和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

你的算法时间复杂度必须是 O(log n) 级别。
如果数组中不存在目标值,返回 [-1, -1]。

例子

Example 1:
Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]

Example 2:
Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]

思想
二分。方法多样化:getFirst用的非递归,getLast用的递归。

解法

class Solution(object):
    def searchRange(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        return [self.getFirst(nums, target), self.getLast(nums, target, 0, len(nums)-1)]
    
    def getFirst(self, nums, target):
        l, r = 0, len(nums) - 1
        while l <= r:
            mid = (l + r) >> 1
            if nums[mid] < target:
                l = mid + 1
            elif nums[mid] > target:
                r = mid - 1
            else:
                if mid == 0 or nums[mid-1] < target:
                    return mid
                r = mid - 1
        return -1
    
    def getLast(self, nums, target, l, r):
        if l > r:
            return -1
        
        mid = (l + r) >> 1
        if nums[mid] < target:
            return self.getLast(nums, target, mid+1, r)
        if nums[mid] > target:
            return self.getLast(nums, target, l, mid-1)
        if mid == len(nums)-1 or nums[mid+1] > target:
            return mid
        return self.getLast(nums, target, mid+1, r)

你可能感兴趣的:(Leetcode)