力扣-33-搜索旋转排序数组

直达链接

旋转数组,想到了剑指Offer-11-旋转数组的最小值

最朴素的想法肯定是,把数组恢复,但是如果这里恢复了,目标值的位置就会变化,达不到要求
如果不恢复,就没法使用二分查找,题目中要求的时间复杂度为O(log n)

评论区提醒:

将数组一分为二,因为旋转后的数组是由两个有序部分组成的,所以不管怎么分,一定是一个有序,另一个有序或部分有序,
有序部分中使用二分查找,另一个部分中递归上述过程

那我怎么知道分完之后是哪一半是有序的,哪一半是无需的?判断最后一个元素是否大于第一个元素?

hahahaha,我自己写的通过了

class Solution {
public:
	int search(vector<int>& nums, int target) {

		return recursion(nums, target, 0, nums.size() - 1);
	}

	// 递归辅助函数
	int recursion(vector<int>& nums, int target,int lowIndex,int highIndex) {

		if (lowIndex > highIndex) return -1;

		int middle = (highIndex - lowIndex) / 2 + lowIndex;

		if (nums[middle] == target) {
			return middle;
		}
		else if (nums[lowIndex] < nums[middle]) {
			// 说明前半部分是有序的
			int n1= binarySearch(nums, target, lowIndex, middle - 1);
			if (n1 != -1) return n1;

			int n2 = recursion(nums, target, middle + 1, highIndex);
			if (n2 != -1) return n2;

			return -1;

		}
		else {
			// 那么就是前半部分可能有序,后半部分一定有序
			int n3 =  binarySearch(nums, target, middle + 1, highIndex);
			if (n3 != -1) return n3;

			int n4 = recursion(nums, target, lowIndex, middle - 1);
			if (n4 != -1) return n4;

			return -1;
		}
	}

	int binarySearch(vector<int>& nums,int target,int lowIndex,int highIndex) {

		while (lowIndex <= highIndex) {
			int middle = (highIndex - lowIndex) / 2 + lowIndex;
			if (nums[middle] == target) {
				return middle;
			}
			else if (nums[middle] > target) {
				highIndex = middle-1;
			}
			else {
				lowIndex = middle+1;
			}
		}
		return -1;
	}
};

posted @ 2022-08-05 14:49  YaosGHC  阅读(29)  评论(0)    收藏  举报