题目
解题思路
第一想法:暴力?
第一个想法就是写一个验证翻转的函数,然后暴力遍历两遍
验证翻转的函数是这样写的,先克隆,再翻转对应区间,最后用equals判断
public static boolean isValidFlip(int[] a, int[] b, int l, int r) {
int[] a_flip = new int[a.length];
// 保留区间[l, r]之前的元素
for (int i = 0; i < l; i++) {
a_flip[i] = a[i];
}
// 翻转区间[l, r]的元素
int index = 0;
for (int j = l; j <= r; j++) {
a_flip[j] = a[r - index];
index++;
}
// 保留区间[r+1, n-1]之后的元素
for (int k = r + 1; k < a.length; k++) {
a_flip[k] = a[k];
}
return Arrays.equals(a_flip, b);
}
显然,结果超时了
优化1
想了一下不用纯暴力了,先找到左右两个数组不相同的地方,再遍历,这样存在一个问题,回文区间左右两个数相同时,同样也是一个方案,因此加上左右的情况。
遍历改成了这样
int left=0;
int right=n-1;
while(right>=0&&a[right]==b[right]){
right--;
}
while(left<n&&a[left]==b[left]){
left++;
}
int count=0;
for(int l=left;l<right;l++){
for(int r=l+1;r<=right;r++){
if(isValidFlip(a,b,l,r)){
count++;
}
}
}
int num=0;
while(left>0&&right<n-1&&b[left-1]==b[right+1]){
num++;
left--;
right++;
}
结论:时间是短了,可是还是超时
优化2
后来考虑到可能是验证翻转函数的问题,改为原地判断,提前返回
public static boolean isValidFlip(int[] a, int[] b, int l, int r) {
// 判断区间翻转后的a是否等于b
for (int i = l; i <= r; i++) {
if (a[i] != b[r - (i - l)]) {
return false;
}
}
// 判断区间外的部分是否相等
for (int i = 0; i < l; i++) {
if (a[i] != b[i]) {
return false;
}
}
for (int i = r + 1; i < a.length; i++) {
if (a[i] != b[i]) {
return false;
}
}
return true;
}
结论:过了
完整代码
import java.util.*;
class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
sc.nextLine();
int[] a = new int[n];
int[] b = new int[n];
for(int i= 0;i<n;i++){
a[i] = sc.nextInt();
}
sc.nextLine();
for(int j = 0;j<n;j++){
b[j] = sc.nextInt();
}
int left=0;
int right=n-1;
while(right>=0&&a[right]==b[right]){
right--;
}
while(left<n&&a[left]==b[left]){
left++;
}
int count=0;
for(int l=left;l<right;l++){
for(int r=l+1;r<=right;r++){
if(isValidFlip(a,b,l,r)){
count++;
}
}
}
int num=0;
while(left>0&&right<n-1&&b[left-1]==b[right+1]){
num++;
left--;
right++;
}
System.out.println(count+num);
}
public static boolean isValidFlip(int[] a, int[] b, int l, int r) {
// 判断区间翻转后的a是否等于b
for (int i = l; i <= r; i++) {
if (a[i] != b[r - (i - l)]) {
return false;
}
}
// 判断区间外的部分是否相等
for (int i = 0; i < l; i++) {
if (a[i] != b[i]) {
return false;
}
}
for (int i = r + 1; i < a.length; i++) {
if (a[i] != b[i]) {
return false;
}
}
return true;
}
}