LeetCode每日一题--完全二叉树的节点个数

简介: LeetCode每日一题--完全二叉树的节点个数

前言


算法的重要性不言而喻!区分度高!

现在学习的门槛低了,只有能上网每个人都可以学编程!培训班6个月就可以培养出来能干活的人,你怎么从这些人中脱颖而出?没错!就是学算法,学一些底层和基础的东西。

说的功利点是为了竞争,卷死对手。真心话说就是能提高自己的基础能力,为技术可持续发展做好充分的准备!!!

提前入门学习书籍:CPrimerPlus、大话数据结构

image.png


刷题网站


代码随想录 (programmercarl.com)

leetcode

我是按照代码随想录提供的刷题顺序进行刷题的,大家也可以去刷leetcode最热200道,都可以

刷题嘛,最重要的就是坚持了!!!


画图软件


OneNote

这个要经常用,遇见不懂的流程的话就拿它画一画!


笔记软件


Typoral


题目


image.png


解析


对递归的图形方式解释 我们随便画了一个二叉树如下:

image.png

那么递归是怎么递归的呢?

我们可以知道递归三要素:

  1. 确定递归的参数和返回值
  2. 递归结束的条件
  3. 单层递归的逻辑

一般递归结束的条件就是该节点为空,好的那递归到那个节点的时候为空了呢?一般都是到叶子节点的时候开始相关计算,如下图:

image.png

我们拿这道题来举例:

计算过程


if (cur == NULL) return 0;
int leftNum = getNodesNum(cur->left);      // 左
int rightNum = getNodesNum(cur->right);    // 右
int treeNum = leftNum + rightNum + 1;      // 中
return treeNum;

代码解析:

  1. 判断指针到叶子结点了
  2. 此时leftNum和rightNum都为0,因为叶子结点已经没有子节点了
  3. 所以treeNum此时等于0+0+1 = 1
  4. 叶子节点计算完毕,在计算其他叶子节点
  5. 计算非叶子节点,同样也是上面的过程,我这里拿B节点举例,到计算B节点时treeNum = 1 + 1 +1 = 3

完整代码


// 版本一
class Solution {
private:
    int getNodesNum(TreeNode* cur) {
        if (cur == NULL) return 0;
        int leftNum = getNodesNum(cur->left);      // 左
        int rightNum = getNodesNum(cur->right);    // 右
        int treeNum = leftNum + rightNum + 1;      // 中
        return treeNum;
    }
public:
    int countNodes(TreeNode* root) {
        return getNodesNum(root);
    }
};

以上为二叉树的通用解法,但题目是完全二叉树的节点个数。

哎,完全二叉树那就不一样了。 完全二叉树只有两种情况:

  1. 满二叉树
  2. 最后一层叶子节点没有满(节点集中在左侧)

满二叉树节点的个数为2^树深度 - 1

那么完全二叉树,可以递归左孩子和右孩子,递归到一定深度一定会有满二叉树,所以也可以用第一种情况来计算

利用完全二叉树的特性计算

1.如何去判断一个左子树或者右子树是不是满二叉树呢?

当递归左子树的深度等于右子树的深度,那就是满二叉树

if(root == null) {
    return 0;
}
int leftDepth = getDepth(root.left);
int rightDepth = getDepth(root.right);
if (leftDepth == rightDepth) {// 左子树是满二叉树
        return (1 << leftDepth) + countNodes(root.right);
    } else {// 右子树是满二叉树
        return (1 << rightDepth) + countNodes(root.left);
}

画图理解代码

image.png

完整代码如下:


class Solution {
    /**
     * 针对完全二叉树的解法
     *
     * 满二叉树的结点数为:2^depth - 1
     */
    public int countNodes(TreeNode root) {
        if(root == null) {
            return 0;
        }
        int leftDepth = getDepth(root.left);
        int rightDepth = getDepth(root.right);
        if (leftDepth == rightDepth) {// 左子树是满二叉树
            // 2^leftDepth其实是 (2^leftDepth - 1) + 1 ,左子树 + 根结点
            return (1 << leftDepth) + countNodes(root.right);
        } else {// 右子树是满二叉树
            return (1 << rightDepth) + countNodes(root.left);
        }
    }
    private int getDepth(TreeNode root) {
        int depth = 0;
        while (root != null) {
            root = root.left;
            depth++;
        }
        return depth;
    }
}



相关文章
|
2月前
|
算法
LeetCode第24题两两交换链表中的节点
这篇文章介绍了LeetCode第24题"两两交换链表中的节点"的解题方法,通过使用虚拟节点和前驱节点技巧,实现了链表中相邻节点的交换。
LeetCode第24题两两交换链表中的节点
|
2月前
|
Python
【Leetcode刷题Python】450. 删除二叉搜索树中的节点
LeetCode上538号问题"把二叉搜索树转换为累加树"的Python实现,使用反向中序遍历并记录节点值之和来更新每个节点的新值。
29 4
【Leetcode刷题Python】450. 删除二叉搜索树中的节点
|
2月前
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
42 5
|
2月前
|
Python
【Leetcode刷题Python】222. 完全二叉树的节点个数
LeetCode第222题"完全二叉树的节点个数"的Python代码实现,通过递归和深度优先遍历的方法来计算给定完全二叉树的节点总数。
22 5
|
2月前
|
Python
【Leetcode刷题Python】剑指 Offer 18. 删除链表的节点
Leetcode题目"剑指 Offer 18. 删除链表的节点"的Python解决方案,通过使用双指针法找到并删除链表中值为特定数值的节点,然后返回更新后的链表头节点。
33 4
|
4月前
|
算法 数据可视化 数据挖掘
哈希表+DFS快速解决力扣129题:求根节点到叶节点数字之和
哈希表+DFS快速解决力扣129题:求根节点到叶节点数字之和
|
4月前
|
存储 SQL 算法
LeetCode 题目 117:填充每个节点的下一个右侧节点指针 II
LeetCode 题目 117:填充每个节点的下一个右侧节点指针 II
|
4月前
|
存储 SQL 算法
LeetCode 题目 116:填充每个节点的下一个右侧节点指针
LeetCode 题目 116:填充每个节点的下一个右侧节点指针
|
4月前
|
存储 SQL 算法
|
4月前
|
SQL 算法 数据挖掘
力扣题目 19:删除链表的倒数第N个节点 【python】
力扣题目 19:删除链表的倒数第N个节点 【python】