返回介绍

solution / 0000-0099 / 0081.Search in Rotated Sorted Array II / README

发布于 2024-06-17 01:04:39 字数 5553 浏览 0 评论 0 收藏 0

81. 搜索旋转排序数组 II

English Version

题目描述

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

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

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

你必须尽可能减少整个操作步骤。

 

示例 1:

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

示例 2:

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

 

提示:

  • 1 <= nums.length <= 5000
  • -104 <= nums[i] <= 104
  • 题目数据保证 nums 在预先未知的某个下标上进行了旋转
  • -104 <= target <= 104

 

进阶:

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

 

解法

方法一:二分查找

我们定义二分查找的左边界 $l=0$,右边界 $r=n-1$,其中 $n$ 为数组的长度。

每次在二分查找的过程中,我们会得到当前的中点 $mid=(l+r)/2$。

  • 如果 $nums[mid] \gt nums[r]$,说明 $[l,mid]$ 是有序的,此时如果 $nums[l] \le target \le nums[mid]$,说明 $target$ 位于 $[l,mid]$,否则 $target$ 位于 $[mid+1,r]$。
  • 如果 $nums[mid] \lt nums[r]$,说明 $[mid+1,r]$ 是有序的,此时如果 $nums[mid] \lt target \le nums[r]$,说明 $target$ 位于 $[mid+1,r]$,否则 $target$ 位于 $[l,mid]$。
  • 如果 $nums[mid] = nums[r]$,说明元素 $nums[mid]$ 和 $nums[r]$ 相等,此时无法判断 $target$ 位于哪个区间,我们只能将 $r$ 减少 $1$。

二分查找结束后,如果 $nums[l] = target$,则说明数组中存在目标值 $target$,否则说明不存在。

时间复杂度近似 $O(\log n)$,空间复杂度 $O(1)$。其中 $n$ 为数组的长度。

class Solution:
  def search(self, nums: List[int], target: int) -> bool:
    n = len(nums)
    l, r = 0, n - 1
    while l < r:
      mid = (l + r) >> 1
      if nums[mid] > nums[r]:
        if nums[l] <= target <= nums[mid]:
          r = mid
        else:
          l = mid + 1
      elif nums[mid] < nums[r]:
        if nums[mid] < target <= nums[r]:
          l = mid + 1
        else:
          r = mid
      else:
        r -= 1
    return nums[l] == target
class Solution {
  public boolean search(int[] nums, int target) {
    int l = 0, r = nums.length - 1;
    while (l < r) {
      int mid = (l + r) >> 1;
      if (nums[mid] > nums[r]) {
        if (nums[l] <= target && target <= nums[mid]) {
          r = mid;
        } else {
          l = mid + 1;
        }
      } else if (nums[mid] < nums[r]) {
        if (nums[mid] < target && target <= nums[r]) {
          l = mid + 1;
        } else {
          r = mid;
        }
      } else {
        --r;
      }
    }
    return nums[l] == target;
  }
}
class Solution {
public:
  bool search(vector<int>& nums, int target) {
    int l = 0, r = nums.size() - 1;
    while (l < r) {
      int mid = (l + r) >> 1;
      if (nums[mid] > nums[r]) {
        if (nums[l] <= target && target <= nums[mid]) {
          r = mid;
        } else {
          l = mid + 1;
        }
      } else if (nums[mid] < nums[r]) {
        if (nums[mid] < target && target <= nums[r]) {
          l = mid + 1;
        } else {
          r = mid;
        }
      } else {
        --r;
      }
    }
    return nums[l] == target;
  }
};
func search(nums []int, target int) bool {
  l, r := 0, len(nums)-1
  for l < r {
    mid := (l + r) >> 1
    if nums[mid] > nums[r] {
      if nums[l] <= target && target <= nums[mid] {
        r = mid
      } else {
        l = mid + 1
      }
    } else if nums[mid] < nums[r] {
      if nums[mid] < target && target <= nums[r] {
        l = mid + 1
      } else {
        r = mid
      }
    } else {
      r--
    }
  }
  return nums[l] == target
}
function search(nums: number[], target: number): boolean {
  let [l, r] = [0, nums.length - 1];
  while (l < r) {
    const mid = (l + r) >> 1;
    if (nums[mid] > nums[r]) {
      if (nums[l] <= target && target <= nums[mid]) {
        r = mid;
      } else {
        l = mid + 1;
      }
    } else if (nums[mid] < nums[r]) {
      if (nums[mid] < target && target <= nums[r]) {
        l = mid + 1;
      } else {
        r = mid;
      }
    } else {
      --r;
    }
  }
  return nums[l] === target;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文