问题描述
给定一个长度为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)。
输出
输出“yes”,如果存在;否则输出“no”,不用输出引号。
样例输入
4
2 1 3 4
样例输出
yes
我的思路
假如数组长度为1或2,直接返回true,输出“yes”
对于其他长度的数组,主要是找到那个降序排列的子串,因为目的是反转子串之后整个数组是增序的
找到第一个 则 (记为 firstIndex )为降序子串的开始,从 firstIndex 开始找到第一个 ,则 (记为lastIndex)是该子串的结束
首先判断 是否为真,当然要提前判断 是否数组越界
真 则返回 false
假 则判断从 开始是否是一直增序的,是则返回true,反之返回false
代码实现
import java.util.Scanner;
public class ArrayReverse {
/**
*
* @param array 传入一个整型数组
* @return boolean 返回是否翻转某个子数组,使得整个数组是按升序排列
* 默认数组中没有相同元素
*/
public static boolean mainCompute(int[] array) {
//设定该数组不为空,且每个整数不同
int len = array.length;
if(len==1||len==2)
return true;
int firstIndex = -1;
int endIndex = -1;
//int secondIndex = -1;
int currentNum = array[0];
//找到第一个数,它比右侧的值大
for(int i = 1; i<len; i++) {
if(currentNum > array[i]) {
firstIndex = i-1;
//System.out.println("firstIndex:"+firstIndex);
break;
}
currentNum = array[i];
}
//如果数组本身就是升序的那么应该返回true?
if(firstIndex == -1)
return true;
currentNum = array[firstIndex+1];
//2 1 3 4 找到1这个位置
for(int j = firstIndex+1; j<len; j++) {
if(currentNum < array[j]) {
endIndex = j-1;
//System.out.println("endIndex:"+endIndex);
break;
}
currentNum = array[j];
}
if(endIndex==-1)
return true;
if(len == endIndex+1) {
return true;
} else {
if(array[firstIndex]>array[endIndex+1])
return false;
currentNum = array[endIndex+1];
for(int m = endIndex+2; m<len; m++) {
if(currentNum>array[m]) {
return false;
}
currentNum = array[m];
}
}
return true;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//接收输入的第一个数字是正整数
String lenStr = sc.nextLine();
int len = Integer.parseInt(lenStr);
int[] array = new int[len];
//接收第二行的 数字数组
String numString = sc.nextLine();
//建立数组
String[] strs = numString.split("\\s+");
//为数组赋值
for(int i = 0; i<len; i++) {
array[i] = Integer.parseInt(strs[i]);
}
if(mainCompute(array)) {
System.out.println("yes");
} else {
System.out.println("no");
}
//最后关闭
sc.close();
}
}
出现的一个问题
在接受两行输入的时候,出现了问题,因为对Scanner不太熟悉,先用了sc.nextInt(),接着用sc.nextLine(); 结果总是读不到第二行的数据
搜了一下,建议两行数据都用sc.nextLine(),指路Scanner之先获取一个数值,再获取一个字符串出错