zoukankan      html  css  js  c++  java
  • A--1-数据结构(2)--二叉树及递归

    B-二叉树专题

    xmind-二叉树专题题目.png

    xmind笔记链接:

    http://note.youdao.com/noteshare?id=65769eb1a96a653e193def55f1a7a7f0

    题目

    1. 三种遍历(递归)
    2. 三种遍历(非递归)(栈)
    3. 层次遍历(节点/层)(队列)
    4. 二叉树最大深度(递归套路)
    5. 判断平衡二叉树(递归套路)
    6. 判断二叉搜索树(递归套路)
    7. 镜像二叉树(递归)
    8. 对称二叉树(递归)
    9. 二叉树中和为某一值的路径(递归回溯)
    10. 重建二叉树 (递归)
    11. 二叉树的最低公共祖先(递归套路)
    12. 二叉搜索树的最低公共祖先
    13. 二叉搜索树的第k大节点
    14. 合并二叉树(递归)
    15. 判断完全二叉树
    16. 二叉树的序列化
    17. 子树判断

    二叉树的遍历

    实际上二叉树的前序中序后序的遍历的递归方法很简单.

    题目1 层次遍历1
    /**
     * 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<int> levelOrder(TreeNode* root) {
                    queue<TreeNode*> q;
                    vector<int> v;
                    if ( ! root )
                            return v;
                    q.push(root);
                    while ( !q.empty() ) 
                    {
                            TreeNode* tmp = q.front();
                            q.pop();
                            if( tmp->left )
                                    q.push(tmp->left);
                            if ( tmp->right)
                                    q.push(tmp->right);
                            v.push_back(tmp->val);
                    }
                    return v;
            }
    };
    

    二叉树的递归套路

    题目1 求二叉树的深度
    /**
     * 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) {
                    return process(root);
            }
            int process(TreeNode* x)
            {
                    if ( x == nullptr)
                            return 0;
    
                    int leftdepth = process(x->left);
                    int rightdepth = process (x->right);
                    return max( leftdepth , rightdepth ) + 1;
                    if (x->right == nullptr && x->left == nullptr)
                            return 1;
            }
    };
    
    题目2 判断一棵树是否为平衡二叉树
    1. 要注意判断条件,空树的情况下,要返回
    /**
     * 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:
    
            class Info {
            public:
                    bool isBalance ;
                    int depth;
                    Info (bool is , int dep) {
                            isBalance = is ;
                            depth = dep;
                    }
            };
    
            bool isBalanced(TreeNode* root) {
                    Info ans = process(root);
                    return ans.isBalance;
            }
    
            Info process( TreeNode* x)
            {
                    // 定义当前树的信息
                    Info info = Info( false, 0 );
                    // 树空的时候,深度0,是平衡二叉树
                    // 这里不return会出错的,因为空的树,就不能由左子树右子树了
                    if ( x == nullptr)
                    {
                            info.isBalance = true;
                            info.depth = 0;
                            return info;
                    }
                    // 从左右子树得到信息
                    Info leftInfo = process( x->left );
                    Info rightInfo = process( x->right );
                    // 根据左右子树的信息,给出树x的信息(深度///是否为平衡二叉树)
                    info.depth = max (leftInfo.depth , rightInfo.depth)+1 ;
                    if ( leftInfo.isBalance == false || rightInfo.isBalance == false)
                    {
                            info.isBalance = false;
                    }
                    if ( (leftInfo.isBalance == true && rightInfo.isBalance == true) 
                            &&  abs(leftInfo.depth - rightInfo.depth) < 2  )
                    {
                            info.isBalance = true;
                    }
                    return info;
            }
    };
    
    题目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:
            class Info{
            public:
                    int maxValue;
                    int minValue;
                    bool isBST;
                    Info (int ma , int mi , bool is ){
                            maxValue = ma;
                            minValue = mi;
                            isBST = is;
                    }
            };
    
            bool isValidBST(TreeNode* root) {
                    Info ans = process(root);
                    return ans.isBST;
            }
    
            Info process(TreeNode* x)
            {
                    Info info = Info( 0 , 0 , false );
                    if ( x == nullptr)
                    {
                            info.isBST = true;
                            info.maxValue = 0;
                            info.minValue = 0;
                            return info;
                    }
                    Info leftInfo = process ( x->left ) ;
                    Info rightInfo  = process (x->right);
                    
                    // 如果左子树或者右子树不是搜索二叉树,那就不用再往下看了,直接返回.
                    if ( leftInfo.isBST == false || rightInfo.isBST == false )
                    {
                            return info;
                    }
                    
                    /*
                        下面的代码罗列了所有当前树是搜索二叉树的可能情况
                        1. 叶子节点
                        2. 只有左孩子
                        3. 只有右孩子
                        4. 左右孩子都有
                        以上四种情况只能发生一种
                    */
                    // 1 当前节点既没有左子树也没有右子树
                    if ( x->left == nullptr && x->right == nullptr)
                    {
                            info.maxValue = x->val ;
                            info.minValue = x->val;
                            info.isBST = true;
                            return info;
                    }
                    // 2 只有右子树
                    if(  (x->left == nullptr && x->right) &&  rightInfo.minValue > x->val )
                    {
                            info.maxValue = max( rightInfo.maxValue , x->val);
                            info.minValue = x->val;
                            info.isBST = true;
                            return info;
                    }
                    // 3 只有左子树
                    if( (x->left  &&  x->right == nullptr)  && leftInfo.maxValue < x->val)  
                    {
                            info.minValue = min( leftInfo.minValue , x->val);
                            info.maxValue = x->val;
                            info.isBST = true;
                            return info;
                    }
                    // 4 当前节点的左子树和右子树都存在
                    if (x->left && x->right &&  x->val > leftInfo.maxValue && x->val < rightInfo.minValue)
                    {
                            info.isBST = true;
                            info.minValue = leftInfo.minValue;
                            info.maxValue = rightInfo.maxValue;
                            return info;
                    }
                    return info;
            }
    };
    
    题目4 镜像二叉树
    /**
     * 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* mirrorTree(TreeNode* root) {
                    process(root);
                    return root;
            }
            void process (TreeNode* x)
            {
                    if ( ! x )
                            return;
                    process(x->left);
                    process(x->right);
    
                    if ( x->right  &&  x->left )
                    {
                            TreeNode* tmp = x->right;
                            x->right = x->left;
                            x->left = tmp;
                            return ;
                    }
                    if ( x->right == nullptr && x->left )
                    {
                            x->right = x->left;
                            x->left = nullptr;
                            return ;
                    }
                    if ( x->right  && x->left == nullptr)
                    {
                            x->left = x->right;
                            x->right = nullptr;
                            return ;
                    }
            }
    };
    
    题目5 是否为对称二叉树
     * 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 process(root->left,root->right);
        }
        bool process(TreeNode* x , TreeNode* y)
        {
            if ( x == nullptr && y == nullptr )
            {
                return true;
            }
            if ( x == nullptr || y == nullptr)
            {
                return false;
            }
            if ( x->val != y->val )
            {
                return false;
            }
            return process (x->left , y->right) && process(x->right,y->left) ;
        }
    };
    
    
    题目6 二叉树中和为某一值的路径(递归回溯)
    /**
     * 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>> pathSum(TreeNode* root, int sum) {
            vector<vector<int>> ans;
            vector<int> path;
            if(root == nullptr)
            {
                return ans ;
            }
            process(root , sum , path ,  ans  );
            return ans;
        }
        void process(  TreeNode* x ,  int sum  ,  vector<int>& path ,
                                        vector<vector<int>>& ans  )
        {
            if( sum == x->val && ( x->left == nullptr && x->right == nullptr))
            {
                path.push_back(x->val);
                ans.push_back( path );
                path.pop_back();
                return ; 
            }
            path.push_back(x->val);
            sum = sum - x->val;
            if ( x->left )
                process(x->left , sum , path,  ans );
            if ( x->right )
                process(x->right , sum , path , ans);
            path.pop_back();
        }
    };
    
    题目 7 重建二叉树
    /**
     * 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* buildTree(vector<int>& preorder, vector<int>& inorder) {
            return process(preorder,inorder);
        }
    
        TreeNode* process(vector<int>& preorder , vector<int>& inorder)
        {
            if (preorder.size() == 0 || inorder.size() == 0)
            {
                return nullptr;
            } 
            TreeNode* x = new TreeNode(preorder[0]);
            int pos = 0;
            for ( int i = 0 ; i < inorder.size(); i ++)
            {
                if( inorder[i] == x->val)
                {
                    pos = i ;
                    break;
                }
            }
            int LeftLen =  pos ; 
    
            vector<int> preorderLeft ( preorder.begin()+1 , preorder.begin()+1 +  LeftLen);
            vector<int> preorderRight ( preorder.begin() + 1 +  LeftLen, preorder.end());
    
            vector<int> inorderLeft (inorder.begin() , inorder.begin() + LeftLen );
            vector<int> inorderRight(inorder.begin() + LeftLen + 1 ,  inorder.end() );
    
            x->left = process (preorderLeft , inorderLeft );
            x->right = process (preorderRight , inorderRight);
    
            return x;
        }
    };
    
    /**
     * 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* buildTree(vector<int>& preorder, vector<int>& inorder) {
            return build(inorder,preorder,0,inorder.size()-1,0,preorder.size()-1);
        }
        TreeNode* build(vector<int>& inorder,vector<int>& preorder, int is,int ie,int ps,int pe) 
        {
            if(inorder.size()==0 || preorder.size()==0)
            {
                return NULL;
            }
            int ll = 0 ; 
            int rl = 0 ; 
            TreeNode* ans = new TreeNode(preorder[ps]);
            for(int i = is; i<= ie; i++)
            {
                if(preorder[ps]==inorder[i])
                {
                    ll = i - is ;
                    rl = ie - i;
                }
            }
            if ( ll > 0 )
            {
                ans->left = build (inorder,preorder,is,is+ll-1,ps+1 ,ps+ll );
            }
            if ( rl > 0 )
            {
                ans->right = build(inorder,preorder,ie-rl+1,ie,pe-rl+1,pe);
            }
            return ans;
        }
    };
    
    题目 8 二叉树的最低公共祖先
    /**
     * 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:
        class Info {
        public:
            TreeNode* ans;
            bool isFindP; 
            bool isFindQ;
            Info( bool b , bool c , TreeNode* k)
            {
                ans = k ; 
                isFindP = b ;
                isFindQ = c;
            }
        };
    
        TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
            Info information = process( root , p , q );
            return information.ans;  
        }
    
    
        Info  process( TreeNode* x  , TreeNode* p , TreeNode* q)
        {
            Info info = Info ( false , false , nullptr ) ;
            if (x == nullptr )
            {
                return info ;
            }
    
            Info leftinfo = process(x->left , p ,q );
            Info rightinfo = process(x->right , p , q);
            
            //  ① 如果左右子树找到了低共,返回左右子树的低共
            if (  leftinfo.ans !=  nullptr )
            {
                return  Info ( true , true , leftinfo.ans );
            }
            if ( rightinfo.ans !=  nullptr )
            {
                return  Info ( true , true , rightinfo.ans );
            }
    
            // ② p 和 q 分布在x的左右子树上, x 是低共
    
            if (  ( leftinfo.isFindP == true && rightinfo.isFindQ == true  ) 
                    ||  (leftinfo.isFindQ == true && rightinfo.isFindP == true) )
            {
                return  Info ( true , true , x );
            }
    
            // ③ x的左右子树上有 p 和 q 的一个
            // ③-① x 的左右子树里有q(p), 且 x 是另一个p(q), x也是低共
            // ③-② x 的左右子树里有q(p), 但是 x 不是p(q)
            bool findp = x==p;
            bool findq = x==q;
            if ( leftinfo.isFindP || rightinfo.isFindP )
            {
                if (findq){
                    return  Info ( true , true , x );
                }else{
                    return  Info ( true , false , nullptr );
                }
            }
            if ( leftinfo.isFindQ || rightinfo.isFindQ )
            {
                if (findp){
                    return  Info ( true , true , x );
                }else{
                    return  Info ( false , true , nullptr );
                }
            }
            // ④ x的左右子树里没有 q ,也没有 p
            return Info( findp , findq , nullptr ) ;
        }
    };
    
    题目9 二叉搜索树的最低公共祖先
    class Solution {
    public:
        TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
            if(p->val<root->val&&q->val<root->val) 
                return lowestCommonAncestor(root->left,p,q);
            if(p->val>root->val&&q->val>root->val) 
                return lowestCommonAncestor(root->right,p,q);
            return root;
        }
    };
    
    题目10 二叉搜索树的第k大节点
    /**
     * 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 kthLargest(TreeNode* root, int k) {
            vector<int> vec;
            process( root, vec);
            return vec[k-1];
    
        }
        void process( TreeNode* x , vector<int>& order)
        {
            if ( x == nullptr )
                return ;
            if (x->right)
                process(x->right , order);
            order.push_back(x->val);
            if (x->left)
                process(x->left, order);
        }
    };
    
    干啥啥不行,吃饭第一名
  • 相关阅读:
    Linux常用命令大全,常用命令总结
    mysql Invalid default value for 'time'
    Laravel 集合 Collection
    WAMP中的mysql设置密码
    laravel jwt 无感刷新token
    laravel tymon/jwt-auth header 发送token
    使用lamp一件安装包 遇到is not within the allowed path(s)的问题
    Linux查看网络和IO性能问题
    jenkins重启导致的项目全部丢失
    算法-排序算法-快速排序
  • 原文地址:https://www.cnblogs.com/jiangxinyu1/p/12407649.html
Copyright © 2011-2022 走看看