算法训练1-day13-二叉树

39 阅读3分钟

今天是二叉树

  1. 110. 平衡二叉树

需要递归检查每个子树是否是平衡二叉树,而不能简单的判断高度

AC代码:

class Solution {
public:
    bool isBalanced(TreeNode* root) {
        return postorder(root);
    }

    bool postorder(TreeNode* root) {
        if (root == nullptr) return true;

        //检查两个子树高度是否相差大于1
        int leftDepth = GetDepth(root->left, 0);
        int rightDepth = GetDepth(root->right, 0);

        if(abs(leftDepth - rightDepth) > 1) return false;

        //在继续检查左右子树是否是平衡二叉树
        return postorder(root->left) && postorder(root->right);
    }

    int GetDepth(TreeNode* root, int depth){
        if (root == nullptr) return depth;

        int leftDepth = GetDepth(root->left, depth + 1);
        int rightDepth = GetDepth(root->right, depth + 1);

        return max(leftDepth,rightDepth);
    }
};

class Solution {
public:
    // 返回以该节点为根节点的二叉树的高度,如果不是平衡二叉树了则返回-1
    int getHeight(TreeNode* node) {
        if (node == NULL) {
            return 0;
        }
        int leftHeight = getHeight(node->left);
        if (leftHeight == -1) return -1;
        int rightHeight = getHeight(node->right);
        if (rightHeight == -1) return -1;
        return abs(leftHeight - rightHeight) > 1 ? -1 : 1 + max(leftHeight, rightHeight);
    }
    bool isBalanced(TreeNode* root) {
        return getHeight(root) == -1 ? false : true;
    }
};
  1. 257. 二叉树的所有路径

AC代码:

class Solution {
public:
    vector<string> ans;
    vector<string> binaryTreePaths(TreeNode* root) {
        GetPath(root, "");
        return ans;
    }

    void GetPath(TreeNode* root, string path) {
        if(root == nullptr) return;
        //判断是否为叶子节点
        if (root->left == nullptr && root->right == nullptr) {
            ans.push_back(path + to_string(root->val));
            return;
        }

        GetPath(root->left, path + to_string(root->val) + "->");
        GetPath(root->right, path + to_string(root->val) + "->");
    }
};
  1. 404. 左叶子之和

AC代码:

class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        return GetSumOfLeftLeaves(root, false);
    }

    int GetSumOfLeftLeaves(TreeNode* root, bool isLeft) {
        if (root == nullptr) return 0;
        if(root->left == nullptr && root->right == nullptr){
            if(isLeft) return root->val;//左叶子
            else return 0;//右叶子
        }

        int leftSum = GetSumOfLeftLeaves(root->left, true);
        int rightSum = GetSumOfLeftLeaves(root->right, false);

        return (leftSum + rightSum);
    }
};
  1. 222. 完全二叉树的节点个数
class Solution {
public:
    int countNodes(TreeNode* root) {
        if (root == nullptr) return 0;
        queue<TreeNode*> nodes;
        nodes.push(root);
        int sum = 0;
        TreeNode* node = nullptr;
        while (!nodes.empty()) {
            int size = nodes.size();
            sum += size;
            for (int i = 0; i < size; ++i) {
                node = nodes.front();
                nodes.pop();

                if (node->left != nullptr)  nodes.push(node->left);
                if (node->right != nullptr) nodes.push(node->right);
            }
        }

        return sum;
    }
};
//O(logn*logn)
class Solution {
public:
    int countNodes(TreeNode* root) {
        if (root == nullptr) return 0;
        //下面求深度所花时间是树的高度,也就是O(h)=(logn)
        //左边
        int leftDepth=1;
        TreeNode* leftNode= root->left;
        while(leftNode != nullptr){
            leftDepth++;
            leftNode = leftNode->left;
        }
        //右边
        int rightDepth=1;
        TreeNode* rightNode= root->right;
        while(rightNode != nullptr){
            rightDepth++;
            rightNode = rightNode->right;
        }
		
		//如果是满二叉树。直接计算节点数
        if(leftDepth == rightDepth) return (1<<leftDepth) - 1;
		
		//如果不是,再分别计算左右子树
		//关键在于完全二叉树的左右子树之中必定有一个是满二叉树
		//因此countNodes(root->left)和countNodes(root->right)之中必定有一个是计算了深度后就直接返回了
		//而对于另外一个不是满二叉树的子树,它自身也是一颗完全二叉树
		//那么处理的逻辑是相同的
		//因此,每一次,我们都能直接使用公式计算出左(或是右)子树的节点数,
		//然后子需要递归另外一边,
		//而对于另外一边,我们依然是能直接使用公式计算出其左(或是右)子树的节点数,
		//从而无需将左右子树都遍历一遍
		//因此,对于每一层,我们都需要计算两次深度,
		//然后直接得出一半的节点数,然后就只需要再看另外一半
		//因此每层耗时O(logn),层数为O(logn)
		//总时间为O(logn*logn)
        return 1 + countNodes(root->left) + countNodes(root->right);
    }
};