二叉树——翻转二叉树、对称二叉树、平衡二叉树、 二叉树路径、二叉树左叶子节点和、路径总和

翻转二叉树
leetcode 翻转二叉树

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
示例 1:
在这里插入图片描述

输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]

BFS

class Solution {
public:
    // 返回类型为 TreeNode* 
    TreeNode* invertTree(TreeNode* root) {
        if (!root) return {};
        queue<TreeNode*> que;
        vector<int> result;
        que.push(root);

        while (!que.empty()) {
            int size = que.size();
            vector<int> level;
            for (int i = 0; i < size; i++) {
                TreeNode* cur = que.front(); // 取出队首元素
                que.pop(); // 出队
                swap(cur->left, cur->right);
                result.push_back(cur->val);
                if (cur->left) que.push(cur->left);
                if (cur->right) que.push(cur->right);
            }
        }
    return root;
    }
};

DFS

class Solution {
public:
    // 返回类型为 TreeNode* 
    TreeNode* invertTree(TreeNode* root) {
       if (!root) return nullptr;
       // 递归翻转左子树和右子树
       TreeNode* temp = invertTree(root->left);
       root->left = invertTree(root->right);
       root->right = temp;
       return root;
    }
};

翻转二叉树

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

示例 1:
在这里插入图片描述

输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if (!root) return true;
        // 调用辅助函数检查左右子树是否对称
        return isSameval(root->left, root->right);
    }


private:
    bool isSameval(TreeNode* t1, TreeNode* t2) {
        // 如果两个子树都为空,则他们是对称的
        if (!t1 && !t2) return true;
        // 如果其中一个子树为空而另外一个不为空,则它们不对称
        if (!t1 || !t2) return false;
        // 检查当前节点的值是否相等,并且左子树的左子树和右子树的右子树、左子树的右子树与右子树的左子树是否对称
        return (t1->val == t2->val) && isSameval(t1->right, t2->left) && isSameval(t1->left, t2->right);
    }
};

完全二叉树的节点个数
二叉树——完全二叉树的节点个数

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层(从第 0 层开始),则该层包含 1~ 2h 个节点。
示例 1:
在这里插入图片描述

输入:root = [1,2,3,4,5,6]
输出:6

BFS

class Solution {
public:
    int countNodes(TreeNode* root) {
        if (!root) return 0;
        queue<TreeNode*> que;
        que.push(root);
        int result = 0;

        while(!que.empty()) {
            int size = que.size();
            for (int i = 0; i < size; i++) {
                TreeNode* cur = que.front(); // 取出队首元素
                que.pop();
                result += 1;
                if (cur->left) que.push(cur->left);
                if (cur->right) que.push(cur->right);
            } 
        }
    return result;
    }
};

给定一个二叉树,判断它是否是 平衡二叉树

示例 1:
在这里插入图片描述

输入:root = [3,9,20,null,null,15,7]
输出:true
class Solution {
public:
    bool isBalanced(TreeNode* root) {
        return getHeight(root) == -1 ? false : true;
    }

    int getHeight(TreeNode* node) {
        // 如果当前节点为空,那么高度为0
        if (node==nullptr) return 0;
        // 递归的计算当前节点 node 的左子树高度
        int leftHight = getHeight(node->left);
        // 如果发现为 -1,即表示左子树中出现了高度差大于 2 的情况,已经不是平衡二叉树了,可以直接返回这个结果给上层
        // 提前推出
        if (leftHight == -1) return -1;
        // 递归的计算当前节点 node 的右子树高度
        int rightHight = getHeight(node->right);
         // 如果发现为 -1,即表示左子树中出现了高度差大于 2 的情况,已经不是平衡二叉树了,可以直接返回这个结果给上层
        if (rightHight == -1) return -1;
        // 说明当前node节点的左子树和右子树没有发现不是平衡二叉树的情况
        // 因此计算一下当前节点 curNode 是否是平衡二叉树
        // 即计算 curNode 的左子树高度与右子树高度差
        // 如果发现小于 2,那么返回以当前节点 curNode 为根节点的子树的最大高度
        // 即节点 curNode 的左右子树中最大高度加 1 
        if (abs(leftHight-rightHight) > 1) return -1;
        else
            return 1 + max(leftHight, rightHight);
    }
};
class Solution:
    def isBalanced(self, root: Optional[TreeNode]) -> bool:
        if self.getHeight(root) == -1:
            return False
        else:
            return True

    def getHeight(self, node: Optional[TreeNode]) -> bool:
        if node == None:
            return 0
        leftHeight = self.getHeight(node.left)
        if leftHeight == -1:
            return -1
        rightHeight = self.getHeight(node.right)
        if rightHeight == -1:
            return -1
        if abs(rightHeight-leftHeight) > 1:
            return -1
        else:
            return 1 + max(leftHeight, rightHeight)      

二叉树的所有路径

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

叶子节点 是指没有子节点的节点。
示例 1:
在这里插入图片描述

输入:root = [1,2,3,null,5]
输出:["1->2->5","1->3"]
解题思路:
1. 前序遍历 (递归寻找中左右)2. path 收集要放在判断叶子结点之前,因为如果一旦到了最下面的一个叶子节点,收集结果后就会直接返回。
3. 返回的类型和参数 (所有的path)4. 终止条件节点的左右子树都为空,将sPath加入到result
class Solution:
    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        if root is None:
            return []
        result = []
        # 注意:这里不再需要接收 traversal 的返回值
        self.traversal(root, [], result)
        print("Final result:", result)  # 调试输出
        return result
    
    def traversal(self, cur, path, result):
        path.append(cur.val)
        if cur.left is None and cur.right is None:  # 当前节点是叶子节点
            sPath = '->'.join(map(str, path))
            result.append(sPath)
            print("Adding path:", sPath)  # 调试输出
        else:
            if cur.left:  # 遍历左子树
                self.traversal(cur.left, path, result)
                path.pop()  # 回溯,移除当前节点
            if cur.right:  # 遍历右子树
                self.traversal(cur.right, path, result)
                path.pop()  # 回溯,移除当前节点
class Solution {
public:
    vector<string> binaryTreePaths(TreeNode* root) {
        if (root == nullptr) {
            return {};
        }
    std:;vector<int> path;
    std::vector<std::string> result;
    traveral(root, path, result);
    std::cout << "Final result";
    for (const auto& str : result) {
        std::cout << str << " ";
    } 
    std::cout << std::endl;
    return result;
   }

    void traveral(TreeNode* cur,  std::vector<int>& path, std::vector<std::string>& result) {
        path.push_back(cur->val);
        if (cur->right == nullptr && cur->left == nullptr) {
            std::string sPath;
            for (auto i = 0; i < path.size(); i++) {
                if (i > 0) sPath += "->";
                sPath += std::to_string(path[i]);
            }
            result.push_back(sPath);
            std::cout << "Adding path" << sPath << std::endl;
        }
        else {
            if (cur->left != nullptr) {
                traveral(cur->left, path, result);  
                path.pop_back(); // 回溯,移除当前节点
            }
            if (cur->right != nullptr) {
                traveral(cur->right, path, result);
                path.pop_back(); // 回溯,移除当前节点
            }
        }
    }
};

左叶子之和

给定二叉树的根节点 root ,返回所有左叶子之和。
示例 1:
在这里插入图片描述

解题思路:
1. 后序遍历. 
2. 递归三部曲 
 2.1 返回类型和传入参数
 2.2 终止条件  cur.left.left == None and cur.left.right == None 但是要注意 cur.left != None
 2.3 单个二叉树的遍历
class Solution:
    def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
        result = []
        self.leteTree(root, result)
        return sum(result)

    def leteTree(self, cur, result):

        if cur.left != None and cur.left.left == None and cur.left.right == None:
            result.append(cur.left.val)

        if cur.left != None:
            self.leteTree(cur.left, result)
        if cur.right != None:
            self.leteTree(cur.right, result)
输入: root = [3,9,20,null,null,15,7] 
输出: 24 
解释: 在这个二叉树中,有两个左叶子,分别是 915,所以返回 24

找树左下角的值
二叉树——找树左下角的值
给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。

假设二叉树中至少有一个节点。
示例 1:
在这里插入图片描述

输入: [1,2,3,4,null,5,6,null,null,7]
输出: 7
class Solution:
    def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:

        queue = deque([root])
        result = None

        while(queue):
            level = []
            for _ in range(len(queue)):
                cur = queue.popleft()
                level.append(cur.val)
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
                result = level[0]
        return result

路径总和
二叉树——路径总和
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。

叶子节点 是指没有子节点的节点。
示例 1:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出:true
解释:等于目标和的根节点到叶节点路径如上图所示。
class Solution:
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        if not root:
            return False
        
        path = []
        traget_bool = False
        traget_bool = self.sumPath(root, path, traget_bool, targetSum)
        return traget_bool
    
    def sumPath(self, cur, path, traget_bool, targetSum):
        # Add the current node's value to the path
        path.append(cur.val)
        
        # Check if it's a leaf node and the path sum equals targetSum
        if cur.left is None and cur.right is None:
            if sum(path) == targetSum:
                traget_bool = True
        
        # If we found a valid path, return immediately
        if traget_bool:
            return traget_bool
        
        # Recursively check left subtree
        if cur.left:
            traget_bool = self.sumPath(cur.left, path, traget_bool, targetSum)
            if traget_bool:  # If a valid path was found in the left subtree, return immediately
                return traget_bool
            path.pop()  # Backtrack
        
        # Recursively check right subtree
        if cur.right:
            traget_bool = self.sumPath(cur.right, path, traget_bool, targetSum)
            if traget_bool:  # If a valid path was found in the right subtree, return immediately
                return traget_bool
            path.pop()  # Backtrack
        
        return traget_bool
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值