Bootstrap

代码随想录算法训练营第十五天|二叉树 part3

110. 平衡二叉树

定义:任意节点的左右子树深度差不超过1。

  1. 参数与返回值的确定,其实也就是函数功能的确定。int getHeight(TreeNode* node)返回当前节点高度,并当不平衡时返回-1.
  2. 终止条件的确定:空节点返回0,
  3. 单层处理逻辑:如果左、右子树高度为-1,则返回-1.如果左、右子树高度差大于1,返回-1.否则返回高度。
class Solution {
public:
    int getHeight(TreeNode* node) {
        if (node == nullptr)
            return 0;
        int leftH = getHeight(node->left);
        if (leftH == -1)
            return -1;
        int rightH = getHeight(node->right);
        if (rightH == -1)
            return -1;
        if (abs(leftH - rightH) > 1)
            return -1;
        return max(leftH, rightH) + 1;
    }
    bool isBalanced(TreeNode* root) {
        int res = getHeight(root);
        if (res == -1)
            return false;
        else 
            return true;
    }
};

257. 二叉树的所有路径

前序遍历二叉树,并将走过的路径记录在path中,当遇到叶子节点时,记录到结果中,然后回退到下一条路径,并将path中节点弹出。

  1. 参数与返回值:void traverse(TreeNode* node, vector<int>& path, vector<int>& result)
  2. 终止条件:如果是叶子节点,则记录result,并返回。
  3. 单层逻辑:将节点值放到path中,遍历左子树和右子树,返回。
class Solution {
public:
    void traverse(TreeNode* node, vector<int>& path, vector<string>& result) {
        path.push_back(node->val);
        if (node->left == nullptr && node->right == nullptr) {
            string tmp;
            for (int i = 0; i < path.size() - 1; ++i) {
                tmp += to_string(path[i]);
                tmp += "->";
            }
            tmp += to_string(path[path.size() - 1]);
            result.push_back(tmp);
            return;
        }
        if (node->left != nullptr) {
            traverse(node->left, path, result);
            path.pop_back();
        }
        if (node->right != nullptr) {
            traverse(node->right, path, result);
            path.pop_back();
        }
        return;
        
    }
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> result;
        vector<int> path;
        if (root == nullptr)
            return result;
        traverse(root, path, result);
        return result;
    }
};

404. 左叶子之和

如何判断是否是左叶子,需要从父节点判断,左节点存在且为叶子节点。

  1. 参数与返回值:int sumOfLeftLeaves(TreeNode* root)给一颗树,返回左叶子节点之和
  2. 终止条件:叶子节点返回0.(因为左叶子节点一定提前被处理了,所以这个肯定是右叶子节点)
  3. 单层逻辑:左子树的左叶子之和+右子树的左叶子之和。
class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        if (root->left == nullptr && root->right == nullptr)
            return 0;
        int left = 0, right = 0;
        if (root->left == nullptr)
            left = 0;
        else {
            if (root->left->left == nullptr && root->left->right == nullptr)
                left = root->left->val;
            else
                left = sumOfLeftLeaves(root->left);
            }

        if (root->right != nullptr)
            right = sumOfLeftLeaves(root->right);
        return left + right;
    }
};

222. 完全二叉树的节点个数

对于所有二叉树适用的后序遍历

class Solution {
public:
    int countNodes(TreeNode* root) {
        if (root == nullptr) return 0;
        
        int left = countNodes(root->left);
        int right = countNodes(root->right);
        return left + right + 1;
    }
};

考虑完全二叉树的特殊情况,满二叉树的节点个数为 2 k − 1 2^k-1 2k1。因此先判断是否为满二叉树,如果是则直接返回;如果不是,左子树节点+右子树节点+1。

class Solution {
public:
    int countNodes(TreeNode* root) {
        if (root == nullptr) return 0;
        int left = 0, right = 0;
        TreeNode* leftnode = root->left;
        TreeNode* rightnode = root->right;
        while (leftnode) {
            leftnode = leftnode->left;
            left++;
        }
        while (rightnode) {
            rightnode = rightnode->right;
            right++;
        }
        if (right == left)
            return (2<<left) - 1;
        left = countNodes(root->left);
        right = countNodes(root->right);
        return left + right + 1;
    }
};
;