作文以记之 ~ 搜索旋转排序数组

0、前言

本篇是力扣上33题的题解,具体题目可 点击此处 进行查看!这个题主要是用于练习二分法,与力扣中 153. 寻找旋转排序数组中的最小值 题有些类似,可以进行对比学习!具体代码实现可 点击此处 进行查看!

1、题目描述

在这里插入图片描述

2、解题思路

2.1 方法1 ~ 利用二分法

2.1.1 思路

这道题中,数组旋转前是有序的,但进行旋转后只保证了数组的局部是有序的,经过分析后可知:

在常规二分查找的时候查看当前 mid 为分割位置分割出来的两个部分 [start, mid][mid + 1, end] 哪个部分是有序的,并根据有序的那个部分确定二分查找的上下界,如此能够根据有序的那部分判断出 target 在不在这个部分。

  • 如果 [start, mid - 1] 是有序数组,且 target 的大小满足nums[start] <= target < nums[mid],则可将搜索范围缩小至 [start, mid - 1],否则在 [mid + 1, end] 中寻找。
  • 如果 [mid, end] 是有序数组,且 target 的大小满足nums[mid+1] < target <= nums[end],则可将搜索范围缩小至 [mid + 1,end],否则在 [start, mid - 1] 中寻找。

2.1.2 程序代码

#include<iostream>
#include<vector>

using namespace std;

void shownums(vector<int>& nums)
{
	for (int& d : nums)
		cout << d << " ";
	cout << endl;
}

int search(vector<int>& nums, int target)
{
	int n = nums.size();
	if (n == 0) return -1;
	if (n == 1) return nums[0] == target ? 0 : -1;
	int start = 0, end = n - 1;
	while (start <= end)
	{
		int mid = start + (end - start) / 2;
		if (nums[mid] == target) return mid;
		if (nums[0] <= nums[mid])//确定前半部分是否有序 -- 此时为 [0,mid]
		{
			if (nums[0] <= target && target < nums[mid])//确定是否存在于当前有序部分数组中,在则确定该部分的结尾end
				end = mid - 1;
			else//不在则确定下一部分的起始位置
				start = mid + 1;
		}
		else
		{
			if (nums[mid] < target && target <= nums[n - 1])
				start = mid + 1;
			else
				end = mid - 1;
		}
	}
	return -1;
}

void test()
{
	vector<int> nums = { 4, 5, 6, 7, 0, 1, 2 };
	int target = 1;
	cout << "\n原数组为:"; shownums(nums); 
	cout << "要查找的值为:" << target << endl; cout << endl;
	cout << "目标数据所在的位置:" << search(nums, target) << endl << endl;
}

int main()
{
	test();
	system("pause");
	return 0;
}

2.1.3 运行结果

在这里插入图片描述

2.2 其他方法

这个题还有其他方法,比如先根据目标数组的最大值确定数组中的有序部分,然后以这两个部分的首尾值判断目标数据所在那个范围,然后再去寻找具体的位置!此种方法实现不难,后续再补充吧!

3、总结

一开始以为的二分法,经过这几天的专项训练,我忽然发现我想得简单了,越学越觉得自己菜,害,加油吧!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值