leetcode刷题之二叉树的修改构造(翻转、构造(最大二叉树、合并二叉树))

二叉树之反转

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

题目 难度:简单

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */

 //前序:中左右
class Solution {
    
    
public:
    TreeNode* invertTree(TreeNode* root) 
    {
    
    
        stack<TreeNode*> sta;
        if(root!=nullptr) sta.push(root);

        while(!sta.empty())
        {
    
    
            TreeNode *node=sta.top();
            swap(node->left,node->right);
            sta.pop();

            if(node->right) sta.push(node->right);
            if(node->left) sta.push(node->left);

        }
        return root;
    }
};

构造二叉树(递归)

构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。
递归的三个步骤:
(1)确定递归函数的参数和返回值
(2)确定终止条件
(3)确定单层递归的逻辑

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

题目 难度:中等
终止条件:中序数组和后序数组的大小为1

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    
    
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) 
    {
    
    

        if (inorder.size() == 0 || postorder.size() == 0) return NULL;
        int last_value=postorder[postorder.size()-1];//后序数组最后一个元素,也就是切割点

        //找切割点的在中序数组的下标
        int lastvalue_index;
        for(int i=0;i<inorder.size();i++)
        {
    
    
            if (last_value==inorder[i])
            {
    
    
                lastvalue_index=i;
            }
        }
        TreeNode* root = new TreeNode(last_value);//根节点

        //叶子节点
        if (inorder.size()==1&&postorder.size() == 1) return root;

        //左闭右开
        //中序左数组
        vector<int> inorder_left(inorder.begin(),inorder.begin()+lastvalue_index);
        //中序右数组
        vector<int> inorder_right(inorder.begin()+lastvalue_index+1,inorder.end());

        //后序左数组
        vector<int> postorder_left(postorder.begin(), postorder.begin() + inorder_left.size());
        //后序右数组
        vector<int> postorder_right(postorder.begin() + inorder_left.size(), postorder.end()-1);
        //postorder.end()-1这里-1是舍弃末尾元素(切割点)


        root->left=buildTree(inorder_left,postorder_left);

        root->right=buildTree(inorder_right,postorder_right);

        return root;

    }
};

654最大二叉树

题目 难度:中等
终止条件:如果传入的数组大小为1,说明遍历到了叶子节点了。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    
    
public:
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) 
    {
    
    
        TreeNode* node=new TreeNode(0);

        //确定终止条件:题目中说了输入的数组大小一定是大于等于1的,所以我们不用考虑小于1的情况
        //那么当递归遍历的时候,如果传入的数组大小为1,说明遍历到了叶子节点了。
        if (nums.size() == 1) 
        {
    
    
            node->val = nums[0];
            return node;
        }

         // 找到数组中最大的值和对应的下标
        // int maxValue = 0;
        // int maxposition= 0;//下标
        // for (int i = 0; i < nums.size(); i++) {
    
    
        //     if (nums[i] > maxValue) {
    
    
        //         maxValue = nums[i];
        //         maxposition = i;
        //     }
        // }
        // node->val = maxValue;
        
        int maxposition=max_element(nums.begin(),nums.end())-nums.begin();//下标
        node->val=nums[maxposition];
        
        //构造左子树
        if(maxposition>=1)//保证左区间至少有一个数值
        {
    
    
            vector<int> leftvec(nums.begin(),nums.begin()+maxposition);
            node->left=constructMaximumBinaryTree(leftvec);
        }

        //构造右子树
        if(nums.size()-maxposition>1)//确保右区间至少有一个数值。
        {
    
    
            vector<int> rightvec(nums.begin()+maxposition+1,nums.end());
            node->right=constructMaximumBinaryTree(rightvec);
        }
        return node;

    }
};

617合并二叉树

题目 难度:简单
终止条件:有一棵树为空,就返回另一棵树

  1. 方法1:前序遍历(递归)
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    
    
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) 
    {
    
    
        //前序遍历(递归)

        //终止条件
        if(root1==nullptr) return root2;
        if(root2==nullptr) return root1;

        root1->val+=root2->val;//中

        root1->left=mergeTrees(root1->left,root2->left);//左
        root1->right=mergeTrees(root1->right,root2->right);//右

        return root1;
	}
  1. 方法2:层序遍历(迭代)将root1和root2都放进一个queue
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    
    
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) 
    {
    
    
        //层序遍历(迭代)
        queue<TreeNode*> que;

        que.push(root1);
        que.push(root2);

        if (root1 == NULL) return root2;
        if (root2 == NULL) return root1;

        while(!que.empty())
        {
    
    
            TreeNode* node1=que.front();
            que.pop();
            TreeNode *node2=que.front();
            que.pop();
            node1->val+=node2->val;

            // 如果两棵树左节点都不为空,加入队列
            if (node1->left != NULL && node2->left != NULL) 
            {
    
    
                que.push(node1->left);
                que.push(node2->left);
            }
            // 如果两棵树右节点都不为空,加入队列
            if (node1->right != NULL && node2->right != NULL) 
            {
    
    
                que.push(node1->right);
                que.push(node2->right);
            }
            // 当t1的左节点 为空 t2左节点不为空,就赋值过去
            if (node1->left == NULL && node2->left != NULL) 
            {
    
    
                node1->left = node2->left;
            }
            // 当t1的右节点 为空 t2右节点不为空,就赋值过去
            if (node1->right == NULL && node2->right != NULL) 
            {
    
    
                node1->right = node2->right;
            }    
        }

        return root1;
    }
};
  1. 方法3:层序遍历(迭代)将root1和root2放进放进两个queue(自创)
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    
    
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) 
    {
    
    
        //层序遍历(迭代)
        queue<TreeNode*> que1;
        queue<TreeNode*> que2;

        que1.push(root1);
        que2.push(root2);

        if (root1 == NULL) return root2;
        if (root2 == NULL) return root1;

        while(!que1.empty())
        {
    
    
            TreeNode* node1=que1.front();
            que1.pop();
            TreeNode *node2=que2.front();
            que2.pop();
            node1->val+=node2->val;

            // 如果两棵树左节点都不为空,加入队列
            if (node1->left != NULL && node2->left != NULL) 
            {
    
    
                que1.push(node1->left);
                que2.push(node2->left);
            }
            // 如果两棵树右节点都不为空,加入队列
            if (node1->right != NULL && node2->right != NULL) 
            {
    
    
                que1.push(node1->right);
                que2.push(node2->right);
            }
            // 当t1的左节点 为空 t2左节点不为空,就赋值过去
            if (node1->left == NULL && node2->left != NULL) 
            {
    
    
                node1->left = node2->left;
            }
            // 当t1的右节点 为空 t2右节点不为空,就赋值过去
            if (node1->right == NULL && node2->right != NULL) 
            {
    
    
                node1->right = node2->right;
            }    
        }

        return root1;
    }
};

猜你喜欢

转载自blog.csdn.net/mabaizi/article/details/128771912