标签:
Suppose a sorted array 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
).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.
解法1:顺序查找,时间复杂度O(n)。
class Solution { public: int search(vector<int>& nums, int target) { int n = nums.size(), i = 0; while(i < n && target != nums[i]) i++; return i == n ? -1 : i; } };
解法2:旋转数组是分为两个有序数组,因此可以使用二分查找。若数组首元素小于数组尾元素,则数组没有旋转,直接使用二分查找binarySearch即可;否则(1)初始化left=0,right=n-1,取mid=(left+right)/2;(2)如果target==nums[mid],则直接返回mid;否则若nums[left]<nums[mid],说明nums[left, ..., mid-1]是有序的,而nums[mid+1, ... , n-1]是旋转的,对前者调用binarySearch,若没找到再对后者调用search;若nums[left]>nums[mid],说明nums[left, ..., mid-1]是旋转的,而nums[mid+1, ... , n-1]是有序的,对后者调用binarySearch,若没找到再对前者调用search。
class Solution { public: int search(vector<int>& nums, int target) { int n = nums.size(); if (n < 2) return n == 1 ? (target == nums[0] ? 0 : -1) : -1; int res, left = 0, right = n - 1; if (nums[left] < nums[right]) res = binarySearch(nums, left, right, target); else { int mid = (left + right) >> 1; if (target == nums[mid]) res = mid; else if (nums[left] < nums[mid]) { if ((res = binarySearch(nums, left, mid - 1, target)) == -1) { vector<int> tmp(nums.begin() + mid + 1, nums.end()); res = search(tmp, target); res = res == -1 ? -1 : res + mid + 1; } } else { if ((res = binarySearch(nums, mid + 1, right, target)) == -1) { vector<int> tmp(nums.begin(), nums.begin() + mid); res = search(tmp, target); } } } return res; } private: int binarySearch(vector<int>& nums, int left, int right, int key) { if (left > right) return -1; int mid = (left + right) >> 1; if (key == nums[mid]) return mid; else if (key > nums[mid]) return binarySearch(nums, mid + 1, right, key); else return binarySearch(nums, left, mid - 1, key); } };
上面的代码可以进一步优化。通过target和nums[left]、nums[right]、nums[mid]进行比较可以去除接下来一些不必要的查找。对于nums[left]>nums[mid],若target>nums[mid]&&target>nums[right],则下一步只需在nums[left,...,mid-1]中调用search查找;若target>nums[mid]&&target<=nums[right],则下一步只需在nums[mid+1,...,right]中调用binarySearch查找;若target<nums[mid],则下一步只需在nums[left,...,mid-1]中调用search查找。对于nums[left]<nums[mid],若target<nums[mid]&&target<nums[left],则只需在nums[mid+1,...,right]中调用search查找;若target<nums[mid]&&target>=nums[left],则只需在nums[left,...,mid-1]中调用binarySearch查找;若target>nums[mid],则只需在nums[mid+1,...,right]中调用search查找。
[LeetCode]25. Search in Rotated Array旋转数组查找
标签:
原文地址:http://www.cnblogs.com/aprilcheny/p/4875771.html