81搜索旋转排序数组 II(二分查找)

1、题目描述

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] )。

编写一个函数来判断给定的目标值是否存在于数组中。若存在返回 true,否则返回 false。

2、示例

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

3、题解

基本思想:折半查找。不同于第33题,这一题有重复数字,所以为了防止2,2,2,3,2,2,2,2的情况,去除low和hig两头连续重复数字,这是两题的唯一不同。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
class Solution {
public:
	bool search(vector<int>& nums, int target) {
		//简化版:二分查找,旋转点将nums分成两部分,先判断mid在左半部分还是右半部分,之后mid又将剩下部分分成两部分
		//如果10111和11101这种情况下 nums[low] == nums[mid]:low++
		//如果在左半部分根据nums[low]<target&&target<nums[mid]判断位于mid的左边
		//如果在右半部分根据nums[mid]<target&&target<=nums[high]判断位于mid的右边
		int n = nums.size();
		if(n==0)  return -1;
		int low=0, mid, high=n-1;
		while(low<=high)
		{
			mid=(low+high)/2;
			if(nums[mid]==target)
				return true;
			else if(nums[low]==nums[mid])
				low++;
			else if(nums[low]<nums[mid])
			{
				if(nums[low]<=target&&target<nums[mid])
					high=mid-1;
				else
					low=mid+1;
			}
			else
			{
				if(nums[mid]<target&&target<=nums[high])
					low=mid+1;
				else
					high=mid-1;
			}
		}
		return false;
	}
};
class Solution1 {
public:
	bool search(vector<int>& nums, int target) {
		//基本思想:折半查找
		int low, high, mid;
		low = 0;
		high = nums.size() - 1;
		while (low<=high)
		{
			//去除重复数字,防止2,2,2,3,2,2,2,2的情况
			while (low < high && nums[low] == nums[low + 1])
				low++;
			while (low < high && nums[high] == nums[high - 1])
				high--;
			mid = (low + high) / 2;
			if (nums[mid] == target || nums[low] == target || nums[high] == target)
				return true;
			//target落在左半部分
			if (nums[low] < target)
			{
				//target落在左半部分的右半边
				if (nums[mid] < target && nums[mid] > nums[low])
					low = mid + 1;
				//target落在左半部分的左半边
				else
					high = mid - 1;
			}
			//target落在右半部分
			else
			{
				//target落在右半部分的左半边
				if (nums[mid] > target&& nums[mid] < nums[high])
					high = mid - 1;
				//target落在右半部分的右半边
				else
					low = mid + 1;
			}
		}
		return false;
	}
};
int main()
{
	Solution solute;
	vector<int> nums = { 2,2,2,2,2,2,2,2 };
	int target = 4;
	cout << solute.search(nums, target) << endl;
	return 0;
}

 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值