一、问题描述
Description
给定一个二叉树(按照完全二叉树规则以一维数组的形式给出,数组中如果出现0指对应位置没有节点),检查该二叉树是否是镜像对称的。如果是,输出 YES ,否则输出 NO
例如,二叉树 [1,2,2,3,4,4,3] 是镜像对称的,而显然 [1,2,2,3,4,4,4]不是镜像对称的
1
/ \
2 2
/ \ / \
3 4 4 3
又如,下面这个 [1,2,2,0,3,0,3] 不是镜像对称的(这里0表示null即此位置处没有节点):
1
/ \
2 2
\ \
3 3
Input
输入为一行,形如:1 2 2 3 4 4 3
注意输入树中节点数量n大于等1且小于等于1000
Output
判断输入是否对应一棵镜像二叉树,如果是,输出 YES ,否则输出 NO
Sample Input 1
1 2 2 3 4 4 3
Sample Output 1
YES
Sample Input 2
1 2
Sample Output 2
NO
二、问题分析
这段代码是通过检查输入的数组是否满足以下性质来判断二叉树是否是镜像对称的:
- 根节点的值必须相同(数组的第一个元素)。
- 如果树是镜像对称的,那么每个节点的左子树和右子树必须是镜像对称的。
算法的关键思想在于,对于一个满足条件的镜像对称二叉树,当按照完全二叉树的规则将其节点存储在数组中时,数组的特定位置上的元素有以下性质:
- 对于任意节点的索引
i
,其左子节点的索引为2 * i
,右子节点的索引为2 * i + 1
。
基于这个性质,代码中的循环部分按照特定规则(即,位置是1、2、4的倍数时),统计了满足条件的节点数目 h
。然后,代码再次遍历数组,检查满足条件的节点是否在对称位置上,即,a[i]
是否等于 a[k]
,其中 k
是对称位置上的节点。
这个算法的思路是,通过数组的存储位置关系,判断节点是否处于镜像对称的位置上。如果所有满足条件的节点都在对称位置上,那么二叉树就是镜像对称的。
三、完整代码
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int a[]=new int[1000];
int i,n,h,j,k,flag,t;
h=0;
String str;
str=in.nextLine();
String divint[]=str.split(" ");
for(i=0;i<divint.length;i++) {
j=i+1;
a[j]=Integer.parseInt(divint[i]);
if(j==1||j==2||j==4||(j%2==0&&j%4==0))
h++;
}
n=i;
flag=0;
for(j=2;j<=h;j++) {
i=(int) Math.pow(2, (j-1));
k=(int) (Math.pow(2, j)-1);
while(i<k) {
if(a[i]!=a[k])
{
flag=1;
break;
}
i++;
k--;
}
if(flag==1)
break;
}
if(flag==1)
System.out.println("NO");
else
System.out.println("YES");
}
}