LeetCode81 搜索旋转排序数组 II

152 阅读1分钟

题目

  • 已知存在一个按非降序排列的整数数组 nums ,数组中的值不必互不相同。
  • 在传递给函数之前,nums在预先未知的某个下标 k(0 <= 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 。 LeetCode链接

题解

  • nums[mid]==target,则直接返回true;
  • 由于允许重复元素,那么有可能出现nums[left]=nums[mid]=nums[right]的情形;
  • nums[left]<nums[mid],则至少说明从left到mid这段序列是非递减的。进而,如果nums[left]<=target&&target<nums[mid],那么target必定在left到mid-1这段区间中;反之,target在mid+1到right这段区间中;
  • nums[left]==nums[mid],则left++
  • nums[left]>nums[mid],那么从mid到right这段序列是非递减的。进而,如果nums[mid]<target&&target<=nums[right],那么target必定在mid+1到right这段区间中;反之,target在left到mid-1这段区间中。

源码

bool search(int* nums, int numsSize, int target)
{
	int left = 0, right = numsSize - 1, mid;
	while (left <= right)
	{
		mid = (left + right) / 2;
		if (nums[mid] == target)
		{
			return true;
		}
		if (nums[left] < nums[mid])
		{
			if (nums[left] <= target && target < nums[mid])
			{
				right = mid - 1;
			}
			else
			{
				left = mid + 1;
			}
		}
		else if (nums[left] == nums[mid])
		{
			left++;
		}
		else
		{
			if (nums[mid] < target && target <= nums[right])
			{
				left = mid + 1;
			}
			else
			{
				right = mid - 1;
			}
		}
	}
	return false;
}