题意:
给定一棵完全二叉树按照层次遍历的访问序列,对于这棵树的每条边,所表示的价值为这条边两点序号的异或值,求出整棵树所有边的价值和。
解法一(记录父节点)
  我们用一个变量表示当前枚举到的节点下标(从左到右枚举),
从
开始枚举 
  用一个变量表示当前下标为
所代表的节点的父亲节点的下标,
显然刚开始为
  
如下图:
    
  我们的变量是从左到右枚举的,变量
显然也是从左到右枚举 
  我们发现,变量每枚举了两个节点,变量
刚好枚举了一个节点 
  于是我们可以记录下当前已经访问了多少个节点,每访问两个节点后让变量加上
  
于是我们就做完了
  代码: 
 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号