算法小例

翻转数组

题目描述

给定一个长度为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

一.解题思路

1.数组必须要翻转一次, 才符合题意 2.找到数组翻转的起始位置和结束位置   a.起始位置为数组开始降序的前一个元素    b.结束位置为数组降序后开始升序前一个元素                                                 如下图, 数组翻转的元素是a1,a2,a3
《算法小例》
《算法小例》

《算法小例》

3.第一次翻转之后, 检查数组是否为升序

二. 解题代码

#include <iostream>
using namespace std;

int main()
{
    int n;
    cin>>n;
    int aiArr[n];
    int iStartIndex = -1;
    int iEndIndex = -1;
    for(int i=0; i<n; i++)
    {
        cin>>aiArr[i];
        if(i>0&&iStartIndex<0&&aiArr[i]<aiArr[i-1])
        {
            iStartIndex = i-1;
        }
        if(iStartIndex>-1&&iEndIndex<0&&aiArr[i]>aiArr[i-1]&&aiArr[i]>aiArr[iStartIndex])
        {
            iEndIndex = i-1;
        }
    }

    if(iStartIndex<0&&iEndIndex<0)
    {
        cout<<"no"<<endl;
    }
    else
    {
        if(iStartIndex>=0&&iEndIndex<0)
            iEndIndex = n-1;
        for(int i=iStartIndex,j=iEndIndex;i<j;i++,j--)
        {
            int iTemp = aiArr[i];
            aiArr[i] = aiArr[j];
            aiArr[j] = iTemp;
        }
        bool bFind = 0;
        for(int i=0;i<n-1;i++)
        {
            if(aiArr[i]>aiArr[i+1])
            {
                bFind = 1;
                break;
            }
        }
        if(bFind)
        {
            cout<<"no"<<endl;
        }else
        {
            cout<<"yes"<<endl;
        }
    }

    return 0;
}

三. 优质解答

精妙处: 1.从收尾两端寻找翻转数组的开始和结束位置  2.通过翻转数组与排好序的数组进行对比,快速判断翻转能否有序

#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
	int n;
	scanf("%d", &n);
	int arr[n];
    int sortArr[n]; 
		for(int i = 0; i < n; i++){
			scanf("%d", &arr[i]);
			sortArr[i]=arr[i];
		}
		sort(sortArr, sortArr + n);
		int start = 0, end = n - 1;
		while(start < n && arr[start] == sortArr[start])start++;
		while(end >= 0 && arr[end] == sortArr[end])end--;
		bool ok = true;
		while(start < end){
			if(sortArr[start] != arr[end]){
				
				ok = false;
				break;
			}
			start++, end--;
		}
		if(ok)
			printf("yes\n");
		else 
			printf("no\n");
	return 0;
}
点赞