[牛客网]偏移数组查找

本文介绍了一种在已知数组被左移位的情况下,如何使用复杂度为log级别的算法来查找特定元素的方法。首先,通过二分查找确定移位后的数组起始下标,然后在调整后的范围内再次应用二分查找,最终定位目标元素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

有一个排过序的数组,包含n个整数,但是这个数组向左进行了一定长度的移位,例如,原数组为[1,2,3,4,5,6],向左移位5个位置即变成了[6,1,2,3,4,5],现在对于移位后的数组,需要查找某个元素的位置。请设计一个复杂度为log级别的算法完成这个任务。
给定一个int数组A,为移位后的数组,同时给定数组大小n和需要查找的元素的值x,请返回x的位置(位置从零开始)。保证数组中元素互异。

在这里插入图片描述

题目链接

https://www.nowcoder.com/practice/72ff6503455c4a008675e79247ef2a3a?tpId=8&&tqId=11047&rp=1&ru=/activity/oj&qru=/ta/cracking-the-coding-interview/question-ranking

解题步骤

  1. 先通过二分查找, 找偏移后数组起始的下标,
  2. 根据新的下标, 再加上数组的长度, 在这两个区间再进行二分查找, 但是会越界, 故将下标取余即可
  3. 最后返回下标

代码如下

#include <iostream>
#include <cstdlib>
#include <vector>

using namespace std;

int main()
{
	// test 1: vector<int> v = { 8, 9, 1, 2, 3 ,4, 5, 6, 7};
	vector<int> v = { 4, 5, 6, 7, 8, 9, 1, 2, 3 };

	// 先找最小的数, 即偏移后的起始位置
	int left = 0, right = v.size() - 1;
	int mid = right / 2;

	while (left < right)
	{
		if (v[mid] < v[mid - 1])
		{
			break;
		}
		
		if (v[mid] < v[left])
		{
			// 在左边
			right = mid - 1;
		} 
		else 
		{
			// 在右边
			left = mid + 1;
		}
		mid = (right + left) / 2 ;

	}
	// 得到的 mid 就是新的起点
	
	int val;
	cin >> val;

	// 之后可以 mid 为起点, size + mid 为结束
	// 在上面这个区间进行查找
	// 查找会越界, 则取余 size 即可
	
	left = mid;
	right = v.size() + mid - 1;

	while (left <= right)
	{
		mid = (right + left) / 2;

		if (val == v[mid  % v.size()])
		{
			break;
		}
		if (val > v[mid % v.size()])
		{
			left = mid + 1;
		}
		else
		{
			right = mid - 1;
		}
	}
	mid %= v.size();
	if (v[mid] != val)
	{
		cout << "can't find \n" << endl;
		system("pause");
		return 0;
	}
	cout << "the position is: "<< mid << endl;
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值