虽然我们知道js中的精度,范围在-2^53 --- 2^53 次方,正常数值计算不会超,但是这次遇到一个算法题,需要给满二叉树标记序号,由于满二叉树每层的数会以 2^n次方, 会出现指数级别增长.当层数超过53 层,直接爆. 联想到 js有bigInt
给你一棵二叉树的根节点 root
,返回树的 最大宽度 。
树的 最大宽度 是所有层中最大的 宽度 。
每一层的 宽度 被定义为该层最左和最右的非空节点(即,两个端点)之间的长度。将这个二叉树视作与满二叉树结构相同,两端点间会出现一些延伸到这一层的 null
节点,这些 null
节点也计入长度。
题目数据保证答案将会在 32 位 带符号整数范围内。
示例 1:
输入: root = [1,3,2,5,3,null,9]
输出: 4
解释: 最大宽度出现在树的第 3 层,宽度为 4 (5,3,null,9) 。
示例 2:
输入: root = [1,3,2,5,null,null,9,6,null,7]
输出: 7
解释: 最大宽度出现在树的第 4 层,宽度为 7 (6,null,null,null,null,null,7) 。
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var widthOfBinaryTree = function (root) {
class TreeId {
constructor(node, id) {
this.node = node;
this.id = BigInt(id);
}
}
if (root === null) {
return 0;
}
let maxLen = BigInt(0)
let queue = [new TreeId(root, BigInt(1))];
while (queue.length > 0) {
let len = queue.length
//为什么放在循环外
let left = queue[0].id
//这里没有理解
let right = queue[len - 1].id;
// 计算当前层的宽度并更新最大宽度
maxLen = maxLen > (right - left + BigInt(1)) ? maxLen : (right - left + BigInt(1));
// 大整数无法用Math.max
// maxLen = Math.max(maxLen, right - left + 1);
while (len > 0) {
let target = queue.shift();
let curId = target.id;
if (target?.node?.left) {
queue.push(new TreeId(target.node.left, (curId * BigInt(2))))
}
if (target?.node?.right) {
queue.push(new TreeId(target.node.right, (curId * BigInt(2) + BigInt(1))))
}
len--
}
}
return Number(maxLen)
};
对于可能出现超精度的数组计算可以利用 BigInt来灵活处理
可以用在一个整数字面量后面加 n
的方式定义一个 BigInt
,如:10n
,或者调用函数 BigInt()
(但不包含 new
运算符)并传递一个整数值或字符串值,不能用Math方法