赛马网基本算法之--翻转数组

题目描述

给定一个长度为n的整数数组a,元素均不相同,问数组是否存在这样一个片段,只将该片段翻转就可以使整个数组升序排列。其中数组片段[l,r]表示序列a[l], a[l+1], ..., a[r]。原始数组为

a[1], a[2], ..., a[l-2], a[l-1], a[l], a[l+1], ..., a[r-1], a[r], a[r+1], a[r+2], ..., a[n-1], a[n],

将片段[l,r]反序后的数组是

a[1], a[2], ..., a[l-2], a[l-1], a[r], a[r-1], ..., a[l+1], a[l], a[r+1], a[r+2], ..., a[n-1], a[n]。

输入

第一行数据是一个整数:n (1≤n≤105),表示数组长度。

第二行数据是n个整数a[1], a[2], ..., a[n] (1≤a[i]≤109)。

样例输入

4

2 1 3 4

输出

输出“yes”,如果存在;否则输出“no”,不用输出引号。

样例输出

yes

代码如下:
#include<iostream>
#include<vector>
using namespace std;

/*
	1、遍历给定的这组数据;
	2、定义2个变量prev和last分别用来表示第一次出现降序位置和第一次出现升序的位置;
	3、保证从prev到last的值为降序的
	4、判断prev-1位置的值和last+1位置的值,使得旋转后可以成为升序;
*/
bool getResult(vector<int> &data){
	int prev, last;
	prev = last = -1;
	int length = data.size();
	//判断数据的有效性
	if (length == 0 || length == 1){
		return false;
	}
	else{
		//1、先遍历,找出prev以及last的位置
		for (int i = 0; i < length - 1; i++){
			if (data[i + 1] >= data[i] && prev == -1){
				continue;
			}
			else if (data[i + 1] < data[i] && prev == -1){
				prev = i;   //prev>-1
				continue;
			}

			if (prev>-1 && data[i] >= data[i + 1]){
				continue;
			}
			else if (prev > -1 && data[i] < data[i + 1] && last==-1){
				last = i;
				continue;
			}
			//根据以上,就可以找到第一次升和降的位置;

			//如果再出现降序,那么直接返回false;
			if (prev>-1 && last > -1 && data[i] > data[i + 1]){
				return false;
			}
		}
}


	//找到2个值以后,判断反转后是否为升序序列做出判断;
	//如果初始数列为升序;
	if (prev == -1){
		return false;
	}
	//如果初始为降序,那么last=-1;
	if (prev > -1 && last == -1){
		return true;
	}
	 if(prev==0 ){
		if (data[prev] <= data[last + 1]){
			return true;
		}
	}else if (prev > 0){
		 if (data[prev - 1] <= data[last] && data[prev] <= data[last + 1]){
			 return true;
		 }	
	 }
		return false;
}
int main(){
	int n;
	cin >> n;
	vector<int> vec;
	for (int i = 0; i < n;i++)
	{
		int temp;
		cin >> temp;
		vec.push_back(temp);
	}
	bool result = getResult(vec);
	if (result){
		cout << "yes" << endl;
	}
	else{
		cout << "no" << endl;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值