[leetcode初级算法]树总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/summer2day/article/details/84037421

二叉树的最大深度

给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],
3
/
9 20
/
15 7
返回它的最大深度 3 。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int maxDepth(TreeNode* root) {
        if(root==NULL)
            return 0;
        return 1+max(maxDepth(root->left),maxDepth(root->right));
    }
};

验证二叉搜索树

给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
示例 1:

输入:
    2
   / \
  1   3
输出: true
示例 2:
输入:
    5
   / \
  1   4
     / \
    3   6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
     根节点的值为 5 ,但是其右子节点值为 4 

c++代码

方法一:

class Solution {
public:
    bool isValidBST(TreeNode *root) {
        return isValidBST(root, LONG_MIN, LONG_MAX);
    }
    bool isValidBST(TreeNode *root, long mn, long mx) {
        if (!root) return true;
        if (root->val <= mn || root->val >= mx) return false;
        return isValidBST(root->left, mn, root->val) && isValidBST(root->right, root->val, mx);
    }
};

方法二:

进行中序遍历,得到的结果正好是一个有序的。直接判断就可以了。
一般的二叉搜索树是左<=根<右,而这道题设定为左<根<右,那么就可以用中序遍历来做。因为如果不去掉左=根这个条件的话,那么下边两个数用中序遍历无法区分:

   20       20
   /           \
 20           20

它们的中序遍历结果都一样,但是左边的是BST,右边的不是BST。去掉等号的条件则相当于去掉了这种限制条件。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool isValidBST(TreeNode* root) {
        if(!root)
            return true;
        vector<int> vals;
        inorder(root,vals);
        for(int i=1;i<vals.size();i++)
        {
            if(vals[i]<=vals[i-1])
                return false;
        }
        return true;
      
    }
    //中序遍历
    void inorder(TreeNode* root,vector<int> &vals)
    {
        if(!root)
            return;
        inorder(root->left,vals);
        vals.push_back(root->val);
        inorder(root->right,vals);
    }
};

对称二叉树

给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [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

说明:
如果你可以运用递归和迭代两种方法解决这个问题,会很加分。

思路

两个节点A和B对称等价于:
这两个节点上存储的值相等
节点A的左子树节点和节点B的右子树上的节点是对称的
节点A的右子树节点和节点A的左子树上的节点是对称的

c++代码

递归

/**
 * Definition for a binary tree node.
 * 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)
            return true;
        return is(root->left,root->right);
    }
    bool is(TreeNode* p1,TreeNode* p2)
    {
        if(p1==NULL && p2==NULL)
            return true;
        if((p1==NULL&&p2!=NULL) ||(p2==NULL&&p1!=NULL))
            return false;
        return (p1->val==p2->val)&&is(p1->left,p2->right)&&is(p1->right,p2->left);
    }
};

迭代

用栈

/**
 * Definition for a binary tree node.
 * 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)
            return true;
        return is(root->left,root->right);
    }
    bool is(TreeNode* p1,TreeNode* p2)
    {
        stack<TreeNode*> s;
        s.push(p1);
        s.push(p2);
        while(!s.empty())
        {
            
            TreeNode *tmp1=s.top();
            s.pop();
            TreeNode *tmp2=s.top();
            s.pop();
            if(!tmp1&&!tmp2)
                continue;
            if(!tmp1||!tmp2||tmp1->val!=tmp2->val)
                return false;
            s.push(tmp1->left);
            s.push(tmp2->right);
            s.push(tmp1->right);
            s.push(tmp2->left);
        }
        return true;
        
    }
};

二叉树的层次遍历

给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。
例如:
给定二叉树: [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7
返回其层次遍历结果:
[
  [3],
  [9,20],
  [15,7]
]

c++代码

思路:

借助队列,每一层的节点都进入队列,遍历完出队。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        if(!root)
            return {};
        vector<vector<int>> tree;
        queue<TreeNode*> q;
        q.push(root);
        while(!q.empty())
        {
            int size=q.size();//每层有多少个节点数
            vector<int> level;
            while(size--)
            {
                TreeNode *node=q.front();
                q.pop();
                level.push_back(node->val);               
                if(node->left)
                    q.push(node->left);
                if(node->right)
                    q.push(node->right);
                
            }
            tree.push_back(level);
        }
        return tree;
    }
};

二叉树的层次遍历 II

给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
例如:
给定二叉树 [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7
返回其自底向上的层次遍历为:
[
  [15,7],
  [9,20],
  [3]
]

思路:

跟上一题只需要修改一下插入的位置就行了。将每一层的push改成insert

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
        if(!root)
            return {};
        vector<vector<int>> tree;
        queue<TreeNode*> q;
        q.push(root);
        while(!q.empty())
        {
            int size=q.size();//每层有多少个节点数
            vector<int> level;
            while(size--)
            {
                TreeNode *node=q.front();
                q.pop();
                level.push_back(node->val);               
                if(node->left)
                    q.push(node->left);
                if(node->right)
                    q.push(node->right);
                
            }
            tree.insert(tree.begin(),level);
        }
        
        return tree;

    }
};

将有序数组转换为二叉搜索树

将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
给定有序数组: [-10,-3,0,5,9],

一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:

      0
     / \
   -3   9
   /   /
 -10  5

c++代码

思路:

采用二分查找,最中间的数作为根节点,左半部分的中间的数作为根节点的左节点,右半部分中间的数作为根节点的右节点。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        if(nums.empty())
            return NULL;
        int n=nums.size();
        return getTree(nums,0,n-1);
                  
    }
    TreeNode* getTree(vector<int>& nums,int low,int high)
    {
        if(low>high)
            return NULL;
        int mid=low+(high-low)/2;
        TreeNode* node = new TreeNode(nums[mid]);
        node->left=getTree(nums,low,mid-1);
        node->right=getTree(nums,mid+1,high);
        return node;                 
    }   
};


猜你喜欢

转载自blog.csdn.net/summer2day/article/details/84037421