662. 二叉树最大宽度

这篇博客探讨了一个二叉树的最大宽度计算问题,主要关注如何有效地处理节点的左右子节点索引,并解决在极端情况下可能出现的整数越界问题。通过调整索引计算方式,避免了指数级增长导致的越界,确保算法在大规模输入下的正确性和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给定一个二叉树,编写一个函数来获取这个树的最大宽度。树的宽度是所有层中的最大宽度。这个二叉树与满二叉树(full binary tree)结构相同,但一些节点为空。

每一层的宽度被定义为两个端点(该层最左和最右的非空节点,两端点间的null节点也计入长度)之间的长度。

示例 1:

输入: 

           1
         /   \
        3     2
       / \     \  
      5   3     9 

输出: 4
解释: 最大值出现在树的第 3 层,宽度为 4 (5,3,null,9)。
示例 2:

输入: 

          1
         /  
        3    
       / \       
      5   3     

输出: 2
解释: 最大值出现在树的第 3 层,宽度为 2 (5,3)。
示例 3:

输入: 

          1
         / \
        3   2 
       /        
      5      

输出: 2
解释: 最大值出现在树的第 2 层,宽度为 2 (3,2)。
示例 4:

输入: 

          1
         / \
        3   2
       /     \  
      5       9 
     /         \
    6           7
输出: 8
解释: 最大值出现在树的第 4 层,宽度为 8 (6,null,null,null,null,null,null,7)

重点两个:
1)左右节点下标的计算 2 * i 及 2* i + 1

2)如何防止极端情况整数越界。有一个用例是线性的树,所以如果每层都乘以2很快就越界了(2^32即越界)。我们采用每次进入新的一层的时候记录queue 头部的index - 1 作为delta。这样每个坐标都减去delta重新调整为从1开始,而且保持相对位置关系不变,避免了越界。这样用int类型就可以了,否则unsigned long long 都不够用,照样越界。

class Solution {
public:
    int widthOfBinaryTree(TreeNode* root) {
        if (!root) return 0;
        int res = 1;
        queue<TreeNode*> q{{root}};
        list<int> idxlist = {1};

        while (!q.empty()) {
            int size = q.size();
            int deta = idxlist.front() - 1;
            for (int i=0; i<size; ++i) {
                int index = idxlist.front();
                idxlist.pop_front();
                index -= deta;
                TreeNode* tmp = q.front();
                q.pop();
                if (tmp->left) {
                    q.push(tmp->left);
                    idxlist.push_back(2*index);
                } 
                if (tmp->right) {
                    q.push(tmp->right);
                    idxlist.push_back(2*index+1);
                }
            }
            res = max(res, idxlist.back()-idxlist.front()+1);
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值