题目描述
给定一个长度为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]。
java实现
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = Integer.parseInt(scanner.nextLine());
int[] data = new int[n];
for(int i = 0; i < n; i++) {
data[i] = scanner.nextInt();
}
//是否已经翻转过? 题干要求“是否存在这样一个片段”,即只翻转一次
//如果hasReverse=true,即已翻转,但在向后遍历的过程中又遇到元素值比上一个小,即数组不满足一次翻转即有序
boolean hasReverse = false;
//用以标识是否处在 寻找这个需要翻转的“片段”,即向后找比当前元素值小的元素
//对于1 2 5 4 3 6,(遍历从i=1开始,与前一个元素比较)如果处在i=1,i=2,处在向后找大,isLower=false;
//如果处在i=3,即刚好5->4,此时置isLower为true;i=4时,因为4->3,所以也为true;
boolean isLower = false;
//记录前面递增子数组的最后一个元素的值
int endUpper = data[0];
//记录递减的子数组的第一个值,即这个子数组(题干中的数组片段)的最大值
int startLower = data[0];
//记录递减子数组的最后一个值,即子数组的最小值
int endLower = data[0];
String ans = "yes";
for(int i = 1; i < n; i++) {
//当前元素比前一个大
if(data[i] > data[i-1]) {
//isLower为true,即已经走完了递减子数组
//此时需要判断当前元素是否大于startLower(递减子数组的最大值)以及当前元素的前一个(递减数组的最小值)是否大于endUpper
//例如:1 2 5 4 3 6
//i=5时,data[i]=6,data[i-1]=3
//endUpper=2,startLower=5
/*如果data[i-1]=1 < endUpper=2,即data[i-1] < endUpper,翻转过去为1 2 1 4 5 6,不满足,直接返回;
如果data[i]=4 < startLower=5,即data[i] < startLowe,翻转过去为1 2 3 4 5 4,也不满足,直接返回*/
if(isLower) {
if(data[i-1] < endUpper || data[i] < startLower) {
ans = "no";
break;
}
//标记已翻转
hasReverse = true;
//再向后遍历不再是递减,是找递增
isLower = false;
}
//正常递增,需要维护endUpper为递增的最后一个元素的值
endUpper = data[i-1];
}
//当前元素比前一个小
else {
//已经存在一个递减数组了,再有递减即不满足题干
if(hasReverse) {
ans = "no";
break;
}
//第一个元素就开始递减需要特判
if(i == 1) {
//因为在此之前不存在递增数组,所以endUpper置为极小
endUpper = Integer.MIN_VALUE;
//开始递减的子数组的第一个值为data[0]
startLower = data[i-1];
//正在递减
isLower = true;
continue;
}
//第一次碰到递减,维护startLower,并置isLower为true,标记 在递减
if(!hasReverse && !isLower){
startLower = data[i-1];
isLower = true;
}
}
}
scanner.close();
System.out.println(ans);
}
}