• LeetCode·每日一题·662.二叉树最大宽度·递归·迭代


    链接:https://leetcode.cn/problems/maximum-width-of-binary-tree/solution/-by-xun-ge-v-wg8c/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 

    题目

    示例

    思路

    解题思路
    如果你熟悉 二叉树 的 顺序存储,这题就很简单~

    • 普通二叉树 一般采用 链式存储结构 ,比如 二叉链表,三叉链表;
    • 完全二叉树 一般采用 顺序存储结构,比如 数组;
    • 我们熟悉的 堆 就是一棵 完全二叉树,采用数组存储。

    为什么 普通二叉树 不用 顺序存储结构 呢?
    因为 普通二叉树 节点发布不如 完全二叉树 紧凑,发布可能会过于分撒,浪费数组空间

    那么怎么把 二叉树 怎么存在一个 数组 中呢?

    假设数组下标从 1 开始,二叉树 的根结点存储在位置 1,如果根结点有左孩子,左孩子存储在位置 2 = 2 * 1,如果根结点有右孩子,右孩子存储在位置 3 = 2 * 1 + 1。对于存储在位置 i 的结点,如果它有左孩子,左孩子存储在位置 2 * i,如果它有右孩子,右孩子存储在位置 2 * i + 1。

    当我了解了 二叉树 的 顺序存储,那么这题我们只需要对二叉树中的结点做标记就可以了,而这个标记就是该结点在数组中的位置。而每一层的宽度就是:最右侧结点的标记(位置) - 最左侧结点的标记(位置)+ 1。这个 层宽 其实就是存储这层结点所需要的连续存储单元个数 ~

    代码

    【递归】->【中序遍历

    1. /**
    2. * Definition for a binary tree node.
    3. * struct TreeNode {
    4. * int val;
    5. * struct TreeNode *left;
    6. * struct TreeNode *right;
    7. * };
    8. */
    9. int getDepth(struct TreeNode *root) {
    10. if (root == NULL) return 0;
    11. int left = getDepth(root->left);
    12. int right = getDepth(root->right);
    13. return 1 + (left > right ? left : right);
    14. }
    15. void inOrder(struct TreeNode* root, long long *left, long long *right, unsigned long long level, unsigned long long index) {
    16. if (root == NULL) return;
    17. inOrder(root->left, left, right, level + 1, 2*index+1); // 左子节点的下标
    18. if (left[level] == -1) // 先更新同一层左子节点下标后固定不改了
    19. left[level] = index;
    20. else // 更新同一层右子节点的最新下标
    21. right[level] = index;
    22. inOrder(root->right, left, right, level + 1, 2*index+2); // 右子节点的下标
    23. }
    24. int widthOfBinaryTree(struct TreeNode* root){
    25. int depth = getDepth(root); // 获取最大深度
    26. long long left[10240], right[10240]; // 记录每一层的最左、最右子节点下标
    27. unsigned long long level = 0, index = 0; // 当前所处层级,当前节点的下标
    28. for (int i = 0; i < depth; i++) { // 下标初始化为-1
    29. left[i] = -1;
    30. right[i] = -1;
    31. }
    32. inOrder(root, left, right, level, index); // 中序遍历,
    33. long maxWidth = 1; // 每层只有一个节点时宽度为1
    34. for (int i = 0; i < depth; i++) {
    35. if (left[i] != -1 && right[i] != -1) // 存在-1的情况说明该层只有一个节点,无需处理
    36. if (maxWidth < right[i] - left[i] + 1) maxWidth = right[i] - left[i] + 1;
    37. }
    38. return maxWidth;
    39. }
    40. 作者:xun-ge-v
    41. 链接:https://leetcode.cn/problems/maximum-width-of-binary-tree/solution/-by-xun-ge-v-wg8c/
    42. 来源:力扣(LeetCode)
    43. 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    【迭代】->【层次遍历

    1. /**
    2. * Definition for a binary tree node.
    3. * struct TreeNode {
    4. * int val;
    5. * struct TreeNode *left;
    6. * struct TreeNode *right;
    7. * };
    8. */
    9. #define MAX_NUM 20005
    10. int widthOfBinaryTree(struct TreeNode* root){
    11. if (root == NULL) {
    12. return 0;
    13. }
    14. struct TreeNode *q[MAX_NUM];
    15. // 在原节点上修改val值记录不行,有用例会超过int范围,加一个长整型型辅助数组
    16. unsigned long long idxQ[MAX_NUM];
    17. int front = 0;
    18. int rear = 0;
    19. // 根节点赋值为其编号0
    20. // root->val = 0;
    21. idxQ[rear] = 0;
    22. // 根节点入队
    23. q[rear++] = root;
    24. int max = 0;
    25. while (front < rear) {
    26. // 每层宽度:每层最后一个节点的值减去最后一个节点的值+1
    27. // max = fmax(max, q[rear - 1]->val - q[front]->val + 1);
    28. max = fmax(max, idxQ[rear - 1] - idxQ[front] + 1);
    29. // 本层所有元素出队,同时将子节点入队,且对子节点赋值正确的编号
    30. int curLevelSize = rear - front;
    31. for (int i = 0; i < curLevelSize; i++) {
    32. unsigned long long idx = idxQ[front];
    33. struct TreeNode *node = q[front++];
    34. if (node->left != NULL) {
    35. // node->left->val = node->val * 2 + 1;
    36. idxQ[rear] = idx * 2 + 1;
    37. q[rear++] = node->left;
    38. }
    39. if (node->right != NULL) {
    40. // node->right->val = node->val * 2 + 2;
    41. idxQ[rear] = idx * 2 + 2;
    42. q[rear++] = node->right;
    43. }
    44. }
    45. }
    46. return max;
    47. }
    48. 作者:xun-ge-v
    49. 链接:https://leetcode.cn/problems/maximum-width-of-binary-tree/solution/-by-xun-ge-v-wg8c/
    50. 来源:力扣(LeetCode)
    51. 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 相关阅读:
    Python | 今年世界杯哪个队最有可能夺冠?!
    ElasticSearch安装步骤及密码重置
    【Spring面试】二、BeanFactory与IoC容器的加载
    说说我的实习收获
    黑马点评-05缓存穿透问题及其解决方案,缓存空字符串或使用布隆过滤器
    C++ pair的基本用法
    CSS让两个标签在同一行显示并自适应宽度
    Visual Studio 2022即将发布,重磅升级为64位应用程序!
    VS创建的aspx文件下没有设计-拆分-源 并且工具箱中的控件为灰色
    for in 和 for of 区别
  • 原文地址:https://blog.csdn.net/m0_64560763/article/details/126557121