剑11LC153.154 寻找旋转数组中的最小值+33. 81搜索旋转排序数组(旋转数组系列)

45 篇文章 0 订阅
12 篇文章 0 订阅

二分查找

两道题都是旋转数组,153返回最小值,33返回要找的目标值

153. 寻找旋转排序数组中的最小值(无重复)

https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。

例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

154. 寻找旋转排序数组中的最小值 II 剑指11(有重复)

https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/

二分查找的变形,注意到旋转数组的首元素肯定不小于旋转数组的尾元素,设置中间点。

如果中间点大于首元素,说明最小数字在后面一半,如果中间点小于尾元素,说明最小数字在前一半。依次循环。同时,当一次循环中首元素小于尾元素,说明最小值就是首元素。

但是当首元素等于尾元素等于中间值,只能在这个区域顺序查找。

1、中值 > 右值,最小值在右半边,收缩左边界

[3, 4, 5, 1, 2]

if rotateArray[mid] > rotateArray[right]: left = mid

2、明确中值 < 右值,最小值在左半边,收缩右边界

[5, 1, 2, 3, 4]

elif rotateArray[mid] < rotateArray[right]:

或 elif rotateArray[mid] < rotateArray[left]:都行

                    right = mid

154有重复代码

# -*- coding:utf-8 -*-
class Solution:
    def minNumberInRotateArray(self, rotateArray):
        if len(rotateArray) == 0:
            return 0
        left = 0
        right = len(rotateArray) - 1
        minVal = rotateArray[0]
        # 特例:排序数组本身,把前面0个元素搬到最后面(未反转)
        if rotateArray[left] < rotateArray[right]:
            return rotateArray[left]
        else:
            while (right - left) > 1:
                mid = (right + left) // 2
                # mid处于第一区间,最小数在mid右侧,右移left
                # [3, 4, 5, 1, 2]
                if rotateArray[mid] > rotateArray[right]:
                    left = mid
                # mid处于第二区间,最小数在mid左侧,左移right
                # [5, 1, 2, 3, 4]
                elif rotateArray[mid] < rotateArray[left]:
                    right = mid
                # 特例:如果三个数相等,此事只能顺序查找
                elif rotateArray[mid] == rotateArray[left] == rotateArray[right]:
                    flag = False
                    for i in range(1, len(rotateArray)):
                        if rotateArray[i] < minVal:
                            minVal = rotateArray[i]
                            right = i
                            flag = True
                    if flag == False:
                        right = 0
            # 最小数在right指针所指的位置
            minVal = rotateArray[right]
            return minVal
 
Test = Solution()
print(Test.minNumberInRotateArray([3, 4, 5, 1, 2]))
print(Test.minNumberInRotateArray([1, 2, 3, 4, 5]))
print(Test.minNumberInRotateArray([1, 1, 1, 0, 1]))
print(Test.minNumberInRotateArray([1, 0, 1, 1, 1]))
print(Test.minNumberInRotateArray([1, 1, 1]))
print(Test.minNumberInRotateArray([]))
print(Test.minNumberInRotateArray([1]))

153无重复代码

class Solution(object):
    def findMin(self, rotateArray):

        if len(rotateArray) == 0:
            return 0
        left = 0
        right = len(rotateArray) - 1
        minVal = rotateArray[0]
        # 特例:排序数组本身,把前面0个元素搬到最后面(未反转)
        if rotateArray[left] < rotateArray[right]:
            return rotateArray[left]
        else:
            while (right - left) > 1:
                mid = (right + left) // 2
                # mid处于第一区间,最小数在mid右侧,右移left
                # [3, 4, 5, 1, 2]
                if rotateArray[mid] > rotateArray[right]:
                    left = mid
                # mid处于第二区间,最小数在mid左侧,左移right
                # [5, 1, 2, 3, 4]
                elif rotateArray[mid] < rotateArray[left]:
                    right = mid
                # 特例:如果三个数相等,此事只能顺序查找
                # elif rotateArray[mid] == rotateArray[left] == rotateArray[right]:
                #     flag = False
                #     for i in range(1, len(rotateArray)):
                #         if rotateArray[i] < minVal:
                #             minVal = rotateArray[i]
                #             right = i
                #             flag = True
                #     if flag == False:
                #         right = 0
            # 最小数在right指针所指的位置
            minVal = rotateArray[right]
            return minVal

https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/solution/er-fen-cha-zhao-wei-shi-yao-zuo-you-bu-dui-cheng-z/

33. 搜索旋转排序数组(无重复)

https://leetcode-cn.com/problems/search-in-rotated-sorted-array/

假设按照升序排序的数组在预先未知的某个点上进行了旋转。( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。

你可以假设数组中不存在重复的元素。你的算法时间复杂度必须是 O(log n) 级别。

输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4

输入: nums = [4,5,6,7,0,1,2], target = 3
输出: -1
class Solution(object):
    def search(self, nums, target):
        
        if len(nums) == 0:
            return -1

        l = 0
        r = len(nums) - 1

        while l < r:
            mid = l + (r - l) // 2
            if nums[mid] < nums[r]:  # [mid, r]有序
                if nums[mid] < target <= nums[r]:
                    l = mid + 1
                else:
                    r = mid
            else:  # [l, mid]有序
                if nums[l] <= target <= nums[mid]:
                    r = mid
                else:
                    l = mid + 1
        if nums[l] == target:
            return l
        else:
            return -1

https://leetcode-cn.com/problems/search-in-rotated-sorted-array/solution/er-fen-fa-python-dai-ma-java-dai-ma-by-liweiwei141/

81. 搜索旋转排序数组 II(有重复)

https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/

输入: nums = [2,5,6,0,0,1,2], target = 0
输出: true

https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/solution/er-fen-fa-wo-tuo-xie-liao-zhu-xing-jie-shi-python3/

class Solution(object):
    def search(self, nums, target):
        if len(nums) == 0:
            return False
        l = 0
        r = len(nums) - 1
        while l <= r:
            mid = (l + r) // 2
            if nums[mid] == target:
                return True
            if nums[mid] == nums[l] == nums[r]:  # 关键
                l += 1
                r -= 1
            elif nums[mid] >= nums[l]:
                if nums[l] <= target < nums[mid]:
                    r = mid - 1
                else:
                    l = mid + 1
            else:
                if nums[mid] < target <= nums[r]:
                    l = mid + 1
                else:
                    r = mid - 1
        return False


nums = [1,3,1,1,1]
target = 3
s = Solution()
print(s.search(nums, target))

其他解法

https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/solution/er-fen-cha-zhao-by-liweiwei1419/

# 中间元素和右边界比较
class Solution(object):
    def search(self, nums, target):
        if len(nums) == 0:
            return False
        l = 0
        r = len(nums) - 1
        while l < r:
            # mid = l + (r - l + 1) // 2
            mid = (l + r + 1) >> 1
            if nums[mid] < nums[r]:
                # 后面是有序的
                # [2,3,4,5,5,6,6,7]
                if nums[mid] <= target <= nums[r]:
                    l = mid
                else:
                    r = mid - 1
            elif nums[mid] > nums[r]:
                # [3,4,5,5,6,6,7,2]
                if nums[l] <= target <= nums[mid - 1]:
                    r = mid - 1
                else:
                    l = mid
            else:
                assert nums[mid] == nums[r]
                if nums[r] == target:
                    return True
                # 右边不是才删除
                r = r - 1
        # 后处理
        return nums[l] == target

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值