题目
给定一棵包含 个节点的完全二叉树,树上每个节点都有一个权值,按从上到下、从左到右的顺序依次是 ,如下图所示:
现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的节点权值之和最大?
如果有多个深度的权值和同为最大,请你输出其中最小的深度。
注:根的深度是 。
输入格式
第一行包含一个整数 。
第二行包含 个整数 。
输出格式
输出一个整数代表答案。
数据范围
,
输入样例:
7
1 6 5 4 3 2 1
输出样例:
2
解题
方法一:前缀和 双指针
思路
完全二叉树的概念见:【学习笔记】数据结构与算法基础 - 完全二叉树 。
若一棵完全二叉树有 层,那么它的节点数目一定小于等于 。
观察题目给出输入完全二叉树的格式,发现每一层的节点权值都是相邻的,因此可以用前缀和优化求节点权值和,只需要知道每层的节点在数组中是从什么位置开始到什么位置结束的即可,观察发现,下标从 开始时,每层节点的起始下标为 ,因此第 层的起始下标即为 ,结束下标为下一层起始下标减一,也就是 ,那么只要枚举每一层求出每层的节点权值和并维护最大层节点权值和即可。
注意:如果不是满二叉树,最后一层要单独处理。
代码
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
in.nextToken();
int n = (int) in.nval;
long[] s = new long[n + 1];
for (int i = 1; i <= n; ++i) {
in.nextToken();
s[i] = s[i - 1] + (int) in.nval;
}
long mx = Integer.MIN_VALUE;
int mx_dep = 1, x = 1, l = 1;
for (; Math.pow(2, x) - 1 <= n; ++x, l *= 2) {
long curr = s[l * 2 - 1] - s[l - 1];
if (curr > mx) {
mx = curr;
mx_dep = x;
}
}
if (l <= n && s[n] - s[l - 1] > mx) mx_dep = x;
System.out.println(mx_dep);
}
}
评论区