day 17 18 20二叉树

根据树的特殊性进行验证

110. 平衡二叉树
根据平衡二叉树条件,从根节点出发看左右子树高度,在递归看左右子树是不是平衡二叉树

class Solution {
public:
    bool isBalanced(TreeNode* root) {
        if(!root) return true;
        int left = height(root->left);
        int right = height(root->right);
        if(abs(left - right) >= 2) return false;
        return isBalanced(root->left) && isBalanced(root->right);

    }

    int height(TreeNode * root){
        if(!root) return 0;
        return max(height(root->left), height(root->right)) + 1;

    }


};

递归找特定叶子节点

404. 左叶子之和
整体遍历(前中后序都可以,因为不涉及出栈节点的特殊操作)从爷爷的视角来找这个左叶子

class Solution {
public:
    int sum = 0;
    int sumOfLeftLeaves(TreeNode* root) {
         dfs(root);
         return sum;
    }
    void dfs(TreeNode * root){
        if(!root) return; 
        if(!root->left && !root->right) return;
        if(root->left && !root->left->left && !root->left->right) sum += root->left->val;
        dfs(root->left);
        //if(root->left && !root->left->left && !root->left->right) sum += root->left->val;
        dfs(root->right);
        //if(root->left && !root->left->left && !root->left->right) sum += root->left->val;
      
    }
};

513. 找树左下角的值

1.递归
题目 在树的最后一行找到最左边的值。也就是深度最大的叶节点的第一个值
任何一种遍历都行(前序 中序,后序因为不涉及拿出节点时的操作)只要是保证左优先即可
2. 层序遍历,判断是不是最后一层的第一个值

class Solution {
public:
    int depth_max = -1;
    int value;
    int findBottomLeftValue(TreeNode* root) {
        dfs(root, 0);
        return value;
    }

    void dfs(TreeNode* root, int depth){
        if(!root) return;
        if(!root->left && !root->right){
            if(depth_max < depth){
                value = root->val;
                depth_max = depth;
            }
        }
        dfs(root->left, depth+1);
        dfs(root->right, depth+1);

    }
};
**class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        queue<TreeNode*> que;
        if (root != NULL) que.push(root);
        int result = 0;
        while (!que.empty()) {
            int size = que.size();
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                if (i == 0) result = node->val; // 记录最后一行第一个元素
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
        }
        return result;
    }
};**

构造二叉树

106. 从中序与后序遍历序列构造二叉树

第一步:如果数组大小为零的话,说明是空节点了。

第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。(如果是前序数组那就是第一个元素作为节点元素,在中序数组中找位置)

第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点

第四步:切割中序数组,切成中序左数组和中序右数组

第五步:切割后序数组,切成后序左数组和后序右数组

第六步:递归处理左区间和右区间

class Solution {
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        return build(inorder, postorder, 0, inorder.size()-1, 0, postorder.size()-1);
    }
    TreeNode* build(vector<int>& inorder, vector<int>& postorder, int inorder_l, int inorder_r, int postorder_l, int postorder_r){
        if(inorder_l > inorder_r) return nullptr;
        int mid;
        for(int i = inorder_l; i<= inorder_r; i++){
            if(inorder[i] == postorder[postorder_r]){
                mid = i;
            }
        }
        TreeNode * node = new TreeNode(inorder[mid]);
        node->left = build(inorder, postorder, inorder_l, mid-1, postorder_l, postorder_l + (mid - inorder_l-1));
        node->right = build(inorder, postorder, mid+1, inorder_r, postorder_l + mid - inorder_l, postorder_r-1);
        return node;

    }
};

654. 最大二叉树
第一步:如果数组大小为零的话,说明是空节点了。

第二步:如果不为空,最大元素作为节点元素,并且作为切割点,切割左右子树

第三步:递归的生成左右子树

class Solution {
public:
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        return build(nums, 0, nums.size()-1);
    }
    TreeNode*build(vector<int>&nums, int left, int right){
        if(left > right) return nullptr;
        int max = nums[left];
        int mid = left;
        for(int i=left; i<=right; i++){
            if(nums[i] > max){
                max = nums[i];
                mid = i;
            }
        }
        TreeNode *node = new TreeNode(nums[mid]);
        node->left = build(nums, left, mid-1);
        node->right = build(nums, mid+1, right);
        return node;
    }
};

617合并二叉树

如果没有返回值,只是一味的看value root1->val += root2->val; 很容易造成重复叠加,不好判断。
步骤一:当前值修改
步骤二:递归建立左子树
步骤三:递归建立右子树
递归出口:两个都为空, 一方未空返回另一端

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        if(!root1 && ! root2) return nullptr;
        if(root1 && root2){
            root1->val += root2->val;
            root1->left = mergeTrees(root1->left, root2->left);
            root1->right = mergeTrees(root1->right, root2->right);
        }
        if(!root1) return root2;
        return root1;

    }
};

路径回溯

257. 二叉树的所有路径
回溯 问题就在于string的回溯 注意递归几次就回溯几次
cur 记录该递归整体回溯的位置
now 记录的访问左右子树之后的回溯位置

class Solution {
public:
    vector<string>result;
    string path;
    vector<string> binaryTreePaths(TreeNode* root) {
        dfs(root);
        return result;
    }
    void dfs(TreeNode * root){
        if(!root) return;
        string cur = path;
        path = path + to_string(root->val);
        if(!root->left&& !root->right){
            result.push_back(path);
            return;
        }
        path  = path + "->";
        string now = path;

        if(root->left){
              dfs(root->left);
              path = now;
        }
        if(root->right){
             dfs(root->right);
             path = now;
        }
        path = cur;
    }
};

112. 路径总和

class Solution {
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(!root) return false;
        if(!root->left && !root->right){
           
            if(targetSum == root->val) return true;
        }
        return hasPathSum(root->left, targetSum - root->val)||
        hasPathSum(root->right, targetSum- root->val);

    }
};

113. 路径总和 II

class Solution {
public:
    vector<vector<int>>result;
    vector<int>path;
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        if(!root) return result;
        path.push_back(root->val);
        dfs(root, targetSum-root->val);
        return result;
    }
    void dfs(TreeNode* root, int targetSum){
         if(!root) return;
         if(!root->left && !root->right && targetSum == 0){
            result.push_back(path);
            return;
        }
        
        if(root->left){
            path.push_back(root->left->val);
            dfs(root->left, targetSum - root->left->val);
            path.pop_back();
        }
        if(root->right){
            path.push_back(root->right->val);
            dfs(root->right, targetSum - root->right->val);
            path.pop_back();
        }

    }
};
  1. 路径总和 III
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值