【LeetCode 二分查找专项】搜索旋转排序数组 II(81)

1. 题目

已知存在一个按非降序排列的整数数组 nums ,数组中的值可能相同。

在传递给函数之前,nums 在预先未知的某个下标 k0 <= k < nums.length)上进行了 旋转 ,使数组变为 [nums[k], nums[k + 1], ..., nums[n - 1], nums[0], nums[1], ..., nums[k - 1]](下标从 0 0 0 开始 计数)。例如: [0, 1, 2, 4, 4, 4, 5, 6, 6, 7] 在下标 5 5 5 处经旋转后可能变为 [4, 5, 6, 6, 7, 0, 1, 2, 4, 4]

给你旋转后的数组 nums 和一个整数 target ,请你编写一个函数来判断给定的目标值是否存在于数组中。如果 nums 中存在这个目标值 target ,则返回 true ,否则返回 false

1.1 示例

  • 示例 1 1 1
  • 输入: nums = [2, 5, 6, 0, 0, 1, 2]target = 0
  • 输出: true
  • 示例 2 2 2
  • 输入: nums = [2, 5, 6, 0, 0, 1, 2]target = 3
  • 输出: false

1.2 说明

1.3 提示

  • 1 ≤ n u m s . l e n g t h ≤ 5000 1 \le nums.length \le 5000 1nums.length5000
  • − 1 0 4 ≤ n u m s [ i ] ≤ 1 0 4 -10^4 \le nums[i] \le 10^4 104nums[i]104
  • 题目数据保证 nums 在预先未知的某个下标上进行了旋转
  • − 1 0 4 ≤ t a r g e t ≤ 1 0 4 -10^4 \le target \le 10^4 104target104

1.4 进阶

  • 这是 搜索旋转排序数组 的延伸题目,本题中的 nums 可能包含重复元素。
  • 这会影响到程序的时间复杂度吗?会有怎样的影响,为什么?

2. 解法一

2.1 分析

此题是 搜索旋转排序数组 的延伸题目,最大的不同在于这里 nums 可能有重复元素,因此 nums[left] == nums[mid]nums[mid] == nums[right] 的时候均无法判断 target 可能在待查找区间的哪一半,但无论如何我们知道:

  • 对于 nums[left] == nums[mid] 时,如果将待查找区间更新为 [left - 1, right] ,此时更新前后待查找区间等价;
  • 对于 nums[mid] == nums[right] 时,将待查找区间更新为 [left, right - 1] ,此时更新前后待查找区间等价。

2.2 解答

from typing import List


class Solution:
    def search(self, nums: List[int], target: int) -> bool:
        left, right = 0, len(nums) - 1
        while left <= right:
            mid = left + (right - left) // 2
            if nums[mid] == target:
                return True
            if nums[left] < nums[mid]:
                if nums[left] <= target < nums[mid]:
                    right = mid - 1
                else:
                    left = mid + 1
            elif nums[left] == nums[mid]:
                left += 1
            elif nums[mid] < nums[right]:
                if nums[mid] < target <= nums[right]:
                    left = mid + 1
                else:
                    right = mid - 1
            elif nums[mid] == nums[right]:
                right -= 1
        return False


def main():
    # nums = [2, 5, 6, 0, 0, 1, 2]
    # nums = [1, 0, 1, 1, 1]
    nums = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1]
    target = 2
    sln = Solution()
    print(sln.search(nums, target))  # True


if __name__ == '__main__':
    main()

  • 执行用时: 28 ms , 在所有 Python3 提交中击败了 94.37% 的用户;
  • 内存消耗: 15 MB , 在所有 Python3 提交中击败了 78.54% 的用户。
  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 nums 的长度。最坏情况下数组元素均相等且不为 target ,我们需要访问所有位置才能得出结果;
  • 空间复杂度: O ( 1 ) O(1) O(1)

猜你喜欢

转载自blog.csdn.net/weixin_37780776/article/details/120024980
今日推荐