leetcode刷题笔记-树2

leetcode 101:

/*

给定一个二叉树,检查它是否是镜像对称的。

例如,二叉树 [1,2,2,3,4,4,3] 是对称的。

    1
   / \
  2   2
 / \ / \
3  4 4  3


但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:

    1
   / \
  2   2
   \   \
   3    3

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/symmetric-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
/*
解析,深度优先搜索 左树的左节点和右树的右节点相等,左树的右节点和右树的左节点相等
*/
#include
#include

 struct TreeNode {
     
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {
     }
 };
 
class Solution {
     
public:
    bool isSymmetric(TreeNode* root) {
     
        if (root == NULL)
        {
     
            return true;
        }
        else
        {
     
            return DFS(root->left,root->right);
        }
        

    }
    bool DFS(TreeNode *rootleft,TreeNode *rootright)
    {
     
        //左右都是NULL 那就是镜像的
        if (rootleft == NULL && rootright == NULL)
        {
     
            return true;
        }
        //左右一个是NULL 一个不是 就不是镜像的
        if ((rootleft == NULL && rootright != NULL) || (rootleft != NULL && rootright == NULL))
        {
     
            return false;
        }
        //当前是不是相同的以及是否左树的左节点和右树的右节点相等,左树的右节点和右树的左节点相等
        auto res = rootleft->val == rootright->val && DFS(rootleft->left, rootright->right) && DFS(rootleft->right,rootright->left);
        return res;
    }
};

leetcode 104:

/*
给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
*/
#include 
#include 
using namespace std;

struct TreeNode
{
     
	int val;
	TreeNode* left;
	TreeNode* right;
	TreeNode(int x) :val(x), left(NULL), right(NULL) {
     }
};
class Solution
{
     
public:
	int maxDepth(TreeNode* TreeNode)
	{
     
		if (TreeNode == NULL)        
		{
     
			return 0;
		}
		else
		{
     
			int left_depth = maxDepth(TreeNode->left);
			int right_depth = maxDepth(TreeNode->right);
			return max(left_depth, right_depth) + 1;  //这里一定要加1 要不就一直是0了
		}

	}
};

leetcode 105:

/*
根据一棵树的前序遍历与中序遍历构造二叉树。

注意:
你可以假设树中没有重复的元素。

例如,给出

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:

    3
   / \
  9  20
    /  \
   15   7

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/

/*

前序遍历:根-左-右
中序遍历:左-跟-右
所以前序遍历的第一个是根节点,在中序里面找到这个点,分成左右两边就是左子树和右子树,然后在把左子树和右子树递归

*/
#include
#include
using std::vector;



  struct TreeNode {
     
      int val;
      TreeNode *left;
      TreeNode *right;
      TreeNode(int x) : val(x), left(NULL), right(NULL) {
     }
  };

class Solution {
     
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
     
        std::cout << "开始" << std::endl;
        if (preorder.size() == 0 || inorder.size() == 0)
        {
     
            return NULL;
        }
        else
        {
     
            return  build(preorder,0,preorder.size()-1,inorder,0,inorder.size()-1);
        }

    
    }
public:
    TreeNode* build(vector<int>& preorder, int ps, int pe, vector<int>& inorder, int is, int ie)
    {
     
        //创建一个棵树
        TreeNode* root = new TreeNode(preorder[ps]);
        root->left = NULL;
        root->right = NULL;
        //前序遍历的第一个是跟节点
        int rootval = preorder[ps];
        //在中序遍历中找到这个跟节点,分为左右两边,这两边就是左子树和右子树
        //所以在中序里面找到这个点
        int mid = 0;
        for (int i = is; i <= ie; i++)
        {
     
            if (rootval == inorder[i])
            {
     
                mid = i;
                break;
            }
        }
        //左子树的长度
        int leftlen = mid - is;
        int rightlen = ie - mid;
        
        //递归构建左子树
        if (leftlen > 0)
        {
     
            //前序遍历左子树的那一段,中序遍历的左子树的那一段
            root->left = build(preorder, ps+1,ps+leftlen , inorder, is, is+leftlen-1);
        }
        if (rightlen > 0)
        {
     
            root->right = build(preorder,ps+leftlen+1,pe,inorder,is+leftlen+1,ie);
        }
        return root;
    }
};


leetcode 106:
这个题和上一个题方法一样

/*
根据一棵树的中序遍历与后序遍历构造二叉树。根据一棵树的中序遍历与后序遍历构造二叉树。

注意:
你可以假设树中没有重复的元素。

例如,给出

中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:

    3
   / \
  9  20
    /  \
   15   7

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。*/
/*
后序遍历:先左再右在根
中序遍历:左-跟-右
所以后续遍历的最后那个就是根节点,然后到中序遍历中找到那个值分成左右子树
*/

#include
#include
using std::vector;

struct TreeNode {
     
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {
     }
};

class Solution {
     
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
     
        if (inorder.size() == 0 || postorder.size() == 0)
        {
     
            return NULL;
        }
        else
        {
     
            return build(inorder, 0, inorder.size() - 1, postorder, 0, postorder.size() - 1);
        }

    }
public:
    TreeNode* build(vector<int>& inorder, int is, int ie, vector<int>& postorder, int ps, int pe)
    {
     
        //创建一棵树
        TreeNode* root = new  TreeNode(postorder[pe]);
        root->left = NULL;
        root->right = NULL;

        int rootval = postorder[pe];
        //在中序遍历中找到这个跟节点,分为左右两边,这两边就是左子树和右子树
        //所以在中序里面找到这个点
        int mid = 0;
        for (int i = is; i <= ie; i++)
        {
     
            if (rootval == inorder[i])
            {
     
                mid = i;
                break;
            }
        }

        int leftlen = mid - is;
        int rightlen = ie - mid;

        if (leftlen > 0)
        {
     
            root->left = build(inorder, is, is + leftlen - 1, postorder, ps, pe - 1 - rightlen);
        }
        if (rightlen > 0)
        {
     
            root->right = build(inorder, is + leftlen + 1, ie, postorder, pe - rightlen, pe - 1);
        }

        return root;
    }
};

你可能感兴趣的:(C/C++,数据结构与算法)