LeetCode-dfs二叉树练习整理

写在前面

刚开始写博客,希望大家多多支持哈,我的个人动态博客网站链接:flamsteed,在CSDN上面同步更新。

最近做了一些题目,发现dfs竟有些生疏了,所以就到leetcode的dfs分类下面刷题,然后发现二叉树也生疏了=.= 做了几题,感觉值得整理一下,可以加深对二叉树的理解与应用。
另外关于所有二叉树的定义如下:

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

LeetCode 100. Same Tree

Given two binary trees, write a function to check if they are the same or not.
Two binary trees are considered the same if they are structurally identical and the nodes have the same value.

题目大意:判断输入的两棵二叉树是否完全相等

解法:虽然题目很简单,但是本着练习的目的,还是要认真做一下,这里可以有两种做法,recursion和iteration。

(一)recursion:

递归解法思路很简单,递归判断p->left和q->left,p->right和q->right是否是相等的子树。

代码:

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if(p && q){
            if(p->val==q->val){
                return ((isSameTree(p->left,q->left))&&(isSameTree(p->right,q->right)));
            }
            else return false;
        }
        else if(p==NULL && q==NULL){
            return true;
        }
        else return false;
    }
};

(二)iteration:

迭代代码量大一些,用循环代替了函数的递归调用,用队列(vector数组也可以)暂存满足条件的左右孩子。

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if (p == NULL && q == NULL) return true;
        if (p == NULL || q == NULL) return false;
        
        TreeNode *curp = NULL, *curq = NULL;
        
        queue<TreeNode *>qp;
        queue<TreeNode *>qq;
        qp.push(p);
        qq.push(q);
        
        while (!qp.empty() && !qq.empty())
        {
            curp = qp.front();
            qp.pop();
            curq = qq.front();
            qq.pop();
            
            if (curp == NULL && curq == NULL)
                continue;
            if (curp && curq)
            {
                if (curp->val != curq->val) return false;
                qp.push(curp->left);
                qp.push(curp->right);
                qq.push(curq->left);
                qq.push(curq->right);
            }
            else 
                return false;
        }
        if (qp.empty() && qq.empty())
            return true;
            
        return false;
    }
};

101. Symmetric Tree

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

题目大意:判断一棵二叉树是不是左右对称的。

解法:判断一个节点的左子树和右子树是否对称即可,同样是递归和迭代两种解法,这里就写recursion一种了。

代码:

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if(root == NULL) return true;
        return(isSametree(root->left,root->right));
    }

    bool isSametree(TreeNode* p, TreeNode* q){
        if(p && q){
            if(p->val==q->val){
                return ((isSametree(p->left,q->right))&&(isSametree(p->right,q->left)));
            }
            else return false;
        }
        else if(p==NULL && q==NULL){
            return true;
        }
        else{
            return false;
        }
    }
};

102. Binary Tree Level Order Traversal

Given a binary tree, return the level order traversal of its nodes’ values. (ie, from left to right, level by level).

题目大意:把输入的二叉树按层存放在二维数组里面,根的层数为0,存放在第0行。这题难度较前两题稍微加大了一点,所以用两种解法来做,加以练习。

(一)recursion

class Solution {
public:
    vector<vector<int>> res;
    vector<vector<int>> levelOrder(TreeNode* root) {
        if(root==NULL) return res;
        helper(root,0);
        vector<vector<int>> ans;
        for(int i=0; i<res.size(); i++){
            if(!res[i].size()) break;
            ans.push_back({});
            for(int j=0; j<res[i].size(); j++)
                ans[i].push_back(res[i][j]);
        }
        return ans;
    }
    void helper(TreeNode* node, int level){
        res.push_back({});
        res[level].push_back(node->val);
        if(node->left!=NULL)
            helper(node->left,level+1);
        if(node->right!=NULL)
            helper(node->right,level+1);
    }
};

(二)iteration

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> levels;
        if(root==NULL) return levels;
        queue<TreeNode*> q;
        q.push(root);
        int level = 0;
        while(!q.empty()){
            levels.push_back({});
            int level_length = q.size();
            for(int i=0; i<level_length; i++){
                TreeNode* node = q.front();
                q.pop();
                levels[level].push_back(node->val);
                if(node->left!=NULL) q.push(node->left);
                if(node->right!=NULL) q.push(node->right);
            }
            level++;
        }
        return levels;
    }
};

104. Maximum Depth of Binary Tree

Given a binary tree, find its maximum depth.
The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

题目大意:求出一棵二叉树的最大深度,根深度为1.

解法: 递归左子树和右子树的深度然后返回最大的一个就行了。

代码:

class Solution {
public:
    int ans;
    int maxDepth(TreeNode* root) {
        if(root==NULL) return 0;
        return max(1+maxDepth(root->left),1+maxDepth(root->right));
    }
};

105. Construct Binary Tree from Preorder and Inorder Traversal

Given preorder and inorder traversal of a tree, construct the binary tree.

题目大意:给出一棵二叉树的前序和中序便利的数组,求这棵树。

解法:preorder从左开始就是根节点,然后在inorder里面找到这个点的位置,左边就是这个根节点的左子树,右边就是右子树,然后分别再左右递归往下找,同时构建二叉树即可。

代码:

class Solution {
public:
    int findIndex(vector<int>& inorder, int is, int ie, int key){//寻找在inorder数组里的位置
        int index = 0;
        for(int i=is; i<=ie; i++)
            if(inorder[i]==key){
                index = i;
                break;
            }
        return index;
    }
    TreeNode* helper(vector<int>& inorder, int is, int ie, vector<int>& preorder, int ps){
        if(is>ie || ps<0) return NULL;//边界条件
        
        TreeNode* node = new TreeNode(preorder[ps]);
        int index = findIndex(inorder, is, ie, preorder[ps]);
        
        node->left = helper(inorder, is, index-1, preorder, ps+1);
        node->right= helper(inorder, index+1, ie, preorder, ps+index-is+1);
        return node;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(preorder.empty()||inorder.empty())
            return NULL;
        return helper(inorder,0,inorder.size()-1,preorder,0);
    }
};

106. Construct Binary Tree from Inorder and Postorder Traversal

Given inorder and postorder traversal of a tree, construct the binary tree.

题目大意:给出中序和后序遍历,求二叉树。

解法:方法和给出前序和中序的类似,倒着从后序遍历的数组往前,然后在中序里面找到根。

代码:

class Solution {
public:
    
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        return bld(inorder,postorder,0,inorder.size()-1,0,postorder.size()-1);
    }
    
    TreeNode* bld(vector<int>&inorder, vector<int>&postorder, int istart, int iend,
                int pstart,int pend){
        if(istart > iend || pstart > pend)
            return NULL;
        int val = postorder[pend];
        
        int i = istart;
        while(inorder[i] != val) i++;

        TreeNode* root = new TreeNode(val);
        root->left = bld(inorder, postorder, istart, i-1, pstart, pstart+i-istart-1);
        root->right = bld(inorder, postorder, i+1, iend, pend-(iend-i), pend-1);
        return root;
    }
};

110. Balanced Binary Tree

Given a binary tree, determine if it is height-balanced.
For this problem, a height-balanced binary tree is defined as:
a binary tree in which the left and right subtrees of every node differ in height by no more than 1.

题目大意:判断输入的二叉树是不是平衡二叉树(左右子树高度差<=1)。

解法: 先定义每个节点的高度,height§ = 1 + max(height(p->left),height(p->right)),当p点为空时,返回值为-1。

然后再比较左右子树的height差值并判断就行了,伪代码如下:

isBalanced(root):
    if (root == NULL):
        return true
    if (abs(height(root.left) - height(root.right)) > 1):
        return false
    else:
        return isBalanced(root.left) && isBalanced(root.right)

整个的代码:

class Solution {
public:
    bool isBalanced(TreeNode* root) {
        if(root==NULL)
            return true;
        return abs(height(root->left)-height(root->right))<2 && isBalanced(root->left) && isBalanced(root->right);
    }
    int height(TreeNode* root){
        if(root==NULL)
            return -1;
        return 1 + max(height(root->left),height(root->right));
    }
};
发布了6 篇原创文章 · 获赞 21 · 访问量 793

猜你喜欢

转载自blog.csdn.net/u011708337/article/details/104854975
今日推荐