题意:
给定一棵完全二叉树按照层次遍历的访问序列,对于这棵树的每条边,所表示的价值为这条边两点序号的异或值,求出整棵树所有边的价值和。
解法一(记录父节点)
我们用一个变量表示当前枚举到的节点下标(从左到右枚举),
从
开始枚举
用一个变量表示当前下标为
所代表的节点的父亲节点的下标,
显然刚开始为
如下图:
我们的变量是从左到右枚举的,变量
显然也是从左到右枚举
我们发现,变量每枚举了两个节点,变量
刚好枚举了一个节点
于是我们可以记录下当前已经访问了多少个节点,每访问两个节点后让变量加上
于是我们就做完了
代码:
class Solution {
public:
long long tree1(vector<int>& a) {
long long ans=0;
for(int i=1,j=0,c=0;i<a.size();i++){
//i为当前节点,j为当前节点父节点
//c为从第二个开始已经访问的节点个数
c++;
ans+=a[i]^a[j];
if(c%2==0)j++;//每访问两个加一次
}
return ans;
}
}; 时间复杂度: 空间复杂度:,程序中存储了一个有
个整型元素的数组,还有若干个整型或长整型变量,故总的空间复杂度为
解法二(找节点下标规律):
我们观察如下完全二叉树(编号从
开始)
我们很容易发现,若当前节点编号为
,则当前节点的左儿子编号为
,当前节点的右儿子编号为
但是题目中的数组下标是从
开始的,我们可以把所有的计算完后的编号整体向左移动一位
于是我们就做完了(注意判断超界)
代码:
class Solution {
public:
long long tree1(vector<int>& a) {
long long ans=0;
for(int k=1;k<=a.size();k++){
//k为当前节点
if(k*2-1<a.size()){//左儿子
ans+=a[k-1]^a[k*2-1];
}
if(k*2+1-1<a.size()){//右儿子
ans+=a[k-1]^a[k*2+1-1];
}
}
return ans;
}
}; 时间复杂度: 空间复杂度:
,程序中存储了一个有
个整型元素的数组,还有若干个整型或长整型变量,故总的空间复杂度为

京公网安备 11010502036488号