对于一个由一位十进制整数构成的二叉树,如果深度不超过4,可以用一个三位十进制整数构成的数组表示,具体规则如下:
1、百位数表示树的层次L,1<=L<=4;十位数表示在该层次中的位置P,1<=P<=8;个位数表示数值V。
2、数组里,L一定是单增的,也就是说后一个数的L大于等于前一个数的L;
3、对于同一个L,P也是单增的,就是说在L不变的情况下,后一个数的P大于等于前一个数的P。
例如:[ 113, 215, 221 ]
3
/ \
5 1
现在要求这个树所有到叶子节点的路径和,对于例子中,路径和为 (3+5)+(3+1)=12
题目的意思就是给出了几个三位数,比如 113 ,代表的是深度为1 ,左边第1个的数值 为 3 ; 215表示深度为2,左边第1个的数值为5 。。。。。。
样例:
1
/ \
2 3
/ \
4 5
输入:
111
212
223
314
325
输出:
19
解题思路是:
1.读取输入的内容,将三位数拆分,分别用数组bai,数组shi,数组ge存储对应位上的值
2.用数组treeArray构建二叉树,保存ge数组的值
3.遍历数组treeArray,找出所有叶子结点,然后根据叶子节点求出根节点到该叶子结点的路径长度
代码如下:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// 读取输入的内容
List<Integer> input = new ArrayList<Integer>();
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
while(str != null && !str.isEmpty()){
Integer value = Integer.parseInt(str);
if(value==0)
break;
input.add(value);
str = sc.nextLine();
}
int[] A = new int[input.size()];
for (int i = 0; i < A.length; i++) {
A[i] = input.get(i).intValue();
}
int res = resolve(A);
System.out.println(res);
}
static int resolve(int[] A){
// 将三位数拆分,分别用数组bai,数组shi,数组ge存储对应位上的值
int len = A.length;
int[] bai = new int[len];
int[] shi = new int[len];
int[] ge = new int[len];
for (int i = 0; i < len; i++) {
bai[i] = A[i]/100;
shi[i] = A[i]%100/10;
ge[i] = A[i]%10;
}
final int P = 15;
int[] treeArray = new int[P];
for (int i = 0; i < treeArray.length; i++) {
treeArray[i] = Integer.MIN_VALUE;
}
// 用数组treeArray构建二叉树,保存ge数组的值
for(int i = 0 ; i < len;i++){
int loc = bai[i]*(bai[i]-1)/2+shi[i]-1;
treeArray[loc] = ge[i];
}
// 遍历数组treeArray,找出所有叶子结点
int sum = 0;
for (int i = 0; i < P; i++) {
if(treeArray[i] != Integer.MIN_VALUE){
if(i*2+1 >= P || i*2+2>=P){
//是叶子结点
sum+=helper(treeArray,i);
}
if(treeArray[i*2+1] == Integer.MIN_VALUE){
// 是叶子节点
sum+=helper(treeArray,i);
}
}
}
return sum;
}
// 根据叶子节点求出根节点到该叶子结点的路径长度
static int helper(int[] treeArray,int index){
// 是根节点
if(index == 0){
return treeArray[index];
}
if(index %2==1){
// 是左节点
return treeArray[index]+helper(treeArray,(index-1)/2);
}else{
// 是右节点
return treeArray[index]+helper(treeArray,(index-2)/2);
}
}
}
关于判断是否是叶子结点的代码:
if(treeArray[i] != Integer.MIN_VALUE){
if(i*2+1 >= P || i*2+2>=P){
//是叶子结点
sum+=helper(treeArray,i);
}
if(treeArray[i*2+1] == Integer.MIN_VALUE){
// 是叶子节点
sum+=helper(treeArray,i);
}
}
第一个if的意思是:如果当前位置的索引为i,
那么左子节点的索引为i*2+1,右子节点的索引为i*2+2
如果左子节点和右子节点的索引超过treeArray的长度,表明当前索引i在最后一行,则一定是叶子结点
第二个if的意思是:如果满足了第一个if,也就是说当前的索引i不在最后一行,如果它的左子节点为空,那么一定是叶子节点