题意
给定一个二叉树的bfs序,求每条边两个端点的异或值之和
方法一
我们考虑直接记录i点,与i点的父亲,这样直接计算节点i与其父亲的异或值即可。
因为每个节点有两个儿子,所以每当i+2,他的父亲就会改变(即序号加1)
那么我们就可以按照这个规律维护两个指针计算。
class Solution {
public:
/**
*
* @param a int整型vector 表示这棵完全二叉树的Bfs遍历序列的结点编号
* @return long长整型
*/
long long tree1(vector<int>& a) {
int fa = 1;
int son = 2;
bool turn = false;
int n = a.size();
long long ans = 0;
for (;son <= n;++ son) {
ans += a [fa - 1] ^ a [son - 1]; //计算两个端点之间的异或值
turn = !turn;
if (!turn) {
++ fa; //i+2,所以父亲也改变了。
}
}
return ans;
}
};很显然,由于只遍历了一次a,所以时间复杂度和空间复杂度都为 ,其中n为节点的数量。
方法二(找儿子)
我们考虑每个节点i的连线有哪些?
为了不重复计算,我们只考虑节点i与他的儿子之间的连线。
对于一颗完全二叉树,我们可以知道节点i的左儿子为2i,右儿子为2i+1
所以我们可以直接从1-n遍历i,计算i与儿子之间的异或值。
class Solution {
public:
/**
*
* @param a int整型vector 表示这棵完全二叉树的Bfs遍历序列的结点编号
* @return long长整型
*/
long long tree1(vector<int>& a) {
long long ans = 0;
int length = a.size();
for (int i = 1;i <= length;++ i) {
int l_son = i * 2,r_son = i * 2 + 1;
if (l_son <= length) {
ans += a [i - 1] ^ a [l_son - 1]; //左儿子存在,就计算值
}
if (r_son <= length) {
ans += a [i - 1] ^ a [r_son - 1]; //右儿子存在
}
}
return ans;
}
};很显然,由于只遍历了一次a,所以时间复杂度和空间复杂度与方法一相同,都为 ,其中n为节点的数量。

京公网安备 11010502036488号