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);
    }
};
posted @ 2020-03-04 09:24  longlongban  阅读(135)  评论(0编辑  收藏  举报