LeetCode C++ 33. Search in Rotated Sorted Array【二分】中等
发布日期:2021-07-01 02:53:57 浏览次数:4 分类:技术文章

本文共 2959 字,大约阅读时间需要 9 分钟。

You are given an integer array nums sorted in ascending order, and an integer target .

Suppose that nums is rotated at some pivot unknown to you beforehand (i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2] ).

If target is found in the array return its index, otherwise, return -1 .

Example 1:

Input: nums = [4,5,6,7,0,1,2], target = 0Output: 4

Example 2:

Input: nums = [4,5,6,7,0,1,2], target = 3Output: -1

Example 3:

Input: nums = [1], target = 0Output: -1

Constraints:

  • 1 <= nums.length <= 5000
  • -10^4 <= nums[i] <= 10^4
  • All values of nums are unique.
  • nums is guranteed to be rotated at some pivot.
  • -10^4 <= target <= 10^4

题意:给出一个升序排序的数组和一个整数,这一数组在未知的某个点上进行了旋转,如 [1,2,3,4,5,6,7] 可能变为 [4,5,6,7,1,2,3] 。然后需要在数组中搜索目标值,如果存在则返回它的位置。


解法1 顺序搜索

完全没有利用到数组的特征,直接进行最简单的顺序搜索, O ( n ) O(n) O(n) 的时间复杂度:

class Solution {
public: int search(vector
& nums, int target) {
for (int i = 0; i < nums.size(); ++i) if (nums[i] == target) return i; return -1; }};

效率如下,比较感人:

执行用时:16 ms, 在所有 C++ 提交中击败了17.24% 的用户内存消耗:11.3 MB, 在所有 C++ 提交中击败了5.21% 的用户

解法2 找到旋转点

我们可以找到那个旋转点,不是进行数组的恢复(太浪费时间了),而是经过判断,对旋转点的一边进行二分搜索,得到结果。这一算法的整体时间复杂度是 O ( n ) O(n) O(n) ,没有实质的改进。暂时不想写代码。


解法3 利用数组的特征

对于旋转数组,如果将其一分为二,则其中一定有一个是有序的,另一个可能有序也可能无序。对有序部分用二分查找,无序部分再一分为二……这样循环。具体代码如下:

class Solution {
public: int search(vector
& nums, int target) {
int lo = 0, hi = nums.size() - 1; while (lo <= hi) {
int mid = lo + (hi - lo) / 2; if (nums[mid] == target) return mid; else if (nums[mid] < nums[hi]) {
//右半段是有序的 if (nums[mid] < target && target <= nums[hi]) lo = mid + 1; //对右半段二分搜索 else hi = mid - 1; //右半段有序,但不在右半段的范围内,因此对左半段搜索 } else {
//左半段有序 if (target >= nums[lo] && target < nums[mid]) hi = mid - 1; //对左半段二分搜索 else lo = mid + 1; //左半段有序,但不在左半段的范围内,因此对右半段搜索 } } return -1; }};

提交后效率如下:

执行用时:4 ms, 在所有 C++ 提交中击败了82.70% 的用户内存消耗:11.2 MB, 在所有 C++ 提交中击败了5.21% 的用户

递归版代码如下:

class Solution {
private: int binarySearchInRotatedSortedArray(const vector
& a, int l, int r, int t) {
if (l > r) return -1; int mid = l + (r - l) / 2; if (a[mid] == t) return mid; else if (a[mid] < a[r]) {
//右半段有序 return (a[mid] < t && t <= a[r]) ? binarySearchInRotatedSortedArray(a, mid + 1, r, t) : binarySearchInRotatedSortedArray(a, l, mid - 1, t); } else {
//左半段有序 return (t < a[mid] && t >= a[l]) ? binarySearchInRotatedSortedArray(a, l, mid - 1, t) : binarySearchInRotatedSortedArray(a, mid + 1, r, t); } }public: int search(vector
& nums, int target) {
return binarySearchInRotatedSortedArray(nums, 0, nums.size() - 1, target); }};

递归版的效率低一些:

执行用时:8 ms, 在所有 C++ 提交中击败了45.60% 的用户内存消耗:11.4 MB, 在所有 C++ 提交中击败了5.21% 的用户

进阶题目:

转载地址:https://memcpy0.blog.csdn.net/article/details/109193191 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:LeetCode C++ 925. Long Pressed Name【String/Two Pointers】简单
下一篇:LeetCode C++ 119. Pascal‘s Triangle II【Math/Array】简单

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月19日 20时46分35秒