题解 | #判断是不是完全二叉树#
判断是不是完全二叉树
https://www.nowcoder.com/practice/8daa4dff9e36409abba2adbe413d6fae
版本1:
1、先把二叉树层序遍历出来,元素放到一个二维数组里面
2、通过判断每一层元素的个数是否 == 2^h
3、再判断最后一层是否全在左边,这里用到了一个一维数组,判断第一个为空的是否出现在了不为空的元素前,如果出现了就不是完全二叉树
function isComplete(root) {
if(!root) return true;
// 层序遍历
const queue = [], res = [], isAllLeft = [];
queue.push(root);
while(queue.length) {
let size = queue.length;
const temp = [];
while(size--) {
const cur = queue.shift();
temp.push(cur.val);
if(cur.left) {
isAllLeft.push(cur.left.val)
queue.push(cur.left);
} else {
isAllLeft.push('#');
}
if(cur.right) {
isAllLeft.push(cur.right.val);
queue.push(cur.right);
} else {
isAllLeft.push('#');
}
}
res.push(temp);
}
let ohterLevel = true, len = res.length;
// 判断除h层外,其它各层的结点数是否都达到最大个数
for(let i = 0; i < len - 1; i++) {
if(res[i].length != Math.pow(2, i)) {
ohterLevel = false;
}
}
let h = true, firstNull, lastNotNull;
// 判断最后一层是否全部集中在左边
for(let i = 0; i < isAllLeft.length; i++) {
const temp = isAllLeft[i];
if(temp === '#' && !firstNull) {
firstNull = i;
}
if(temp != '#') {
lastNotNull = i;
}
}
if(firstNull < lastNotNull) h = false;
return ohterLevel && h;
}
module.exports = {
isCompleteTree : isCompleteTree
};
上面的代码是第一次写的时候,陷入的误区。虽然也能AC,但是多用了一个二维数组,多做了第二步的判断。
于是有了下面版本2的写法:
直接层序遍历,将元素全部放到一个一维数组 isAllLeft 里面包括为空的,最后判断第一个为空的是否出现在了不为空的前面
function isComplete(root) {
if(!root) return true;
// 层序遍历
const queue = [], isAllLeft = [];
queue.push(root);
while(queue.length) {
let size = queue.length;
while(size--) {
const cur = queue.shift();
if(cur != null) {
isAllLeft.push(cur.val);
} else {
isAllLeft.push('#');
continue;
}
queue.push(cur.left);
queue.push(cur.right);
}
}
let h = true, firstNull, lastNotNull;
for(let i = 0; i < isAllLeft.length; i++) {
const temp = isAllLeft[i];
if(temp === '#' && !firstNull) {
firstNull = i;
}
if(temp != '#') {
lastNotNull = i;
}
}
if(firstNull < lastNotNull) h = false;
return h;
}
版本2的思路是对的,但是代码还是不够简洁。不必使用一个一维数组去存储所有的结点元素,
1、可以借助一个标记位来标记第一个出现的叶子结点,
2、如果在后续的结点遍历中遇到了不是叶子结点的结点,就可以判断这棵树不是完全二叉树了。
就是完全二叉树的特性:
层序遍历完全二叉树,中途不会出现叶子结点。
function isCompleteTree( root ) {
if(!root) return true;
const queue = [];
queue.push(root);
let firstNullFlag = false;
let cur;
while(queue.length) {
cur = queue.shift();
// 标记第一个出现为空的叶子结点
if(cur == null) {
firstNullFlag = true;
continue;
}
// 后续遍历,如果前面出现了叶子结点,就不是完全二叉树了
if(firstNullFlag) {
return false;
}
queue.push(cur.left);
queue.push(cur.right);
}
return true;
}

三奇智元机器人科技有限公司公司福利 74人发布