zoukankan      html  css  js  c++  java
  • 单链表转 BST 树 | 数组转 BST树

    单链表转二叉树

    题目描述
    给定一个单链表,其中的元素按升序排序,请将它转化成平衡二叉搜索树(BST)
    示例1
    输入
    复制
    {-1,0,1,2}
    返回值
    复制
    {1,0,2,-1}
    说明:本题目包含复杂数据结构TreeNode、ListNode,点此查看相关信息

    
    typedef TreeNode Node;
    /**
     * struct TreeNode {
     *	int val;
     *	struct TreeNode *left;
     *	struct TreeNode *right;
     * };
     */
    /**
     * struct ListNode {
     *	int val;
     *	struct ListNode *next;
     * };
     */
    
    class Solution {
    public:
        /**
         * 
         * @param head ListNode类 
         * @return TreeNode类
         */
        TreeNode* sortedListToBST(ListNode* head) {
            // write code here
            return build(head,NULL);
        }
        Node* build(ListNode* head,ListNode* tail) {
            if(head==NULL|| head==tail) return NULL;
            ListNode* first= head,*last=head;
            while(first!=tail && first->next!=tail) first = first->next->next,last = last->next;
            Node *root = new Node(last->val);
            
            root->left = build(head,last);
            root ->right = build(last->next,tail);
            return root;
        }
    };
    
    
    
    
    
    
    
    
    
    
    
    

    升序数组转二叉树

    题目描述
    给出一个升序排序的数组,将其转化为平衡二叉搜索树(BST).
    示例1
    输入
    复制
    [-1,0,1,2]
    返回值
    复制
    {1,0,2,-1}
    说明:本题目包含复杂数据结构TreeNode,点此查看相关信息

    
    
    typedef TreeNode Node;
    class Solution {
    public:
        /**
         * 
         * @param num int整型vector 
         * @return TreeNode类
         */
        TreeNode* sortedArrayToBST(vector<int>& num) {
            if(num.size()<=0) return NULL;
            return build(num,0 ,num.size()-1);
        }
        
        Node* build(vector<int>& a,int l,int r) {
            if(l>r) return nullptr;
    //         if(l==r) return new Node(a[l]);
            int mid = l+r+1>>1;
            Node * root = new Node(a[mid]);
            root ->left = build(a,l,mid-1);
            root ->right = build(a,mid+1,r);
            return root;
            
        }
    };
    
    
    

    中序遍历 和后续遍历序列 生成的二叉树

    题目描述
    给出一棵树的中序遍历和后序遍历,请构造这颗二叉树
    注意:
    保证给出的树中不存在重复的节点
    示例1
    输入
    复制
    [2,1,3],[2,3,1]
    返回值
    复制
    {1,2,3}

    
    
    typedef TreeNode Node;
    
    class Solution {
    public:
        /**
         * 
         * @param inorder int整型vector 
         * @param postorder int整型vector 
         * @return TreeNode类
         */
        TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
            // write code here
            int n = inorder.size(),m = postorder.size();
            if(n!=m) return NULL;
            return build(inorder,postorder,0,n-1,0,n-1);
        }
        
        Node* build(vector<int>&in,vector<int> &post,int il,int ir,int pl,int pr) {
            if(il>ir || pl>pr) return  NULL;
            //post order 左右 [根]  root-> pr
            //inorder  左根右       root-> il+ir/2
            int target = post[pr],in_root_idx=il;
            for(int i=il;i<=ir;++i) {
                if(in[i]==target) {
                    in_root_idx = i;
                    break;
                }
            }
            Node* root = new Node(target);
            int r_to_i = ir - in_root_idx;
            root->left = build(in,post,il,in_root_idx-1,pl,pr-r_to_i-1);
            root->right = build(in,post,in_root_idx+1,ir,pr-r_to_i,pr-1);
            return root;
    
            
        }
        
    };
    
    

    题目描述
    给出一棵树的前序遍历和中序遍历,请构造这颗二叉树
    注意:
    可以假设树中不存在重复的节点
    示例1
    输入
    复制
    [1,2],[1,2]
    返回值
    复制
    {1,#,2}

    
    typedef TreeNode Node;
    typedef vector<int> Array;
    class Solution {
    public:
        /**
         * 
         * @param preorder int整型vector 
         * @param inorder int整型vector 
         * @return TreeNode类
         */
        TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
            // write code here
            int n = preorder.size(),m = inorder.size();
            if(n!=m) return NULL;
            return build(preorder,inorder,0,n-1,0,n-1);
        }
        
        
        
        Node* build(Array &pre,Array &in, int pl,int pr,int il,int ir) {
            if(pl>pr || il>ir) return NULL;
            int target = pre[pl];int root_idx=il;
            for(int i=il;i<=ir;++i) {
                if(in[i]==target){root_idx = i;break;}
            }
            Node* root = new Node(target);
            int len = root_idx - il;
            //先序,根左,右
            root ->left = build(pre,in,pl+1,pl+len,il,root_idx-1);
            root ->right = build(pre,in,pl+len+1,pr,root_idx+1,ir);
            
            return root;
        }
    };
    
    
    
    
    
    
    
    
    
    
    
    

    后序遍历生成BST

    给定一个值n,请生成所有的存储值1...n.的二叉搜索树(BST)的结构
    例如:
    给定n=3,你的程序应该给出下面五种不同的二叉搜索树(BST)

    
    
    typedef TreeNode Node;
    class Solution {
    public:
        /**
         * 
         * @param n int整型 
         * @return TreeNode类vector
         */
        vector<TreeNode*> generateTrees(int n) {
            // write code here
            return build(1,n);
        }
        
        
        vector<Node*> build(int l,int r) {
            if(l>r) return {NULL};
            vector<Node*> res;
            for(int k=l;k<=r;++k) {
                vector<Node*> left = build(l,k-1);
                vector<Node*> right = build(k+1,r);
                for(int i=0;i<left.size();++i) {
                    for(int j=0;j<right.size();++j) {
                        Node* root = new Node(k);
                        root->left = left[i];
                        root->right = right[j];
                        res.push_back(root);
                    }
                }
            }
            return res;
            
            
        }
        
        
        
        
    };
    
    

    输入N 求二叉树生成的个数

    给定一个值n,能构建出多少不同的值包含1...n的二叉搜索树(BST)?
    例如
    给定 n = 3, 有五种不同的二叉搜索树(BST)

    分析:
    f(1) = 1;
    f(2) = f(1)+f(1);
    f(3) = f(2)+f(1)f(1)+f(2);
    f(4) = f(3)+f(1)f(2)+f(2)f(1)+f(3)
    f(5) = f(4)+f(1)f(3)+f(2)f(2)f(3)*f(1)+f(4)
    
    
    
    思路:
        考虑根节点,设对于任意根节点k,有f(k)种树的可能。
        比k小的k-1个元素构成k的左子树。则左子树有f(k-1)种情况。
        比k大的n-k个元素构成k的右子树。则右子树有f(n-k)种情况。
        易知,左右子树相互独立,所以f(k)=f(k-1)*f(n-k)。
        综上,对于n,结果为k取1,2,3,...,n时,所有f(k)的和。
    代码思路:
        根据上述思路可以用简单的递归方法快速解决。
        现在考虑非递归解法,用数组记录每个f(i)的值,记f(0)=1,f(1)=1。
        根据公式:f(k)=f(k-1)*f(n-k),访问数组中的元素。
        循环求和,结果更新到数组中。
    (PS:此题可用Catalan number快速求解:对于n,答案为1/(n+1)*nC2n。)
    
    
    
    
    class Solution {
    public:
        /**
         * 
         * @param n int整型 
         * @return int整型
         */
        int numTrees(int n) {
            // write code here
            if(n<0) return -1;
            if(n==0) return 1;
            int dp[n+1];
            memset(dp,0,sizeof dp);
            dp[0] = 1;
            dp[1] = 1;
            
            for(int i=2;i<=n;++i) {
                for(int j=0;j<i;++j) {
                    dp[i] += dp[j]*dp[i-j-1];
                }
            }
            return dp[n];
            
        }
        
        
    };
    
    
  • 相关阅读:
    9月23日JavaScript作业----用DIV做下拉列表
    9月23日JavaScript作业----日期时间选择
    9月23日JavaScript作业----两个列表之间移动数据
    9月22日下午JavaScript----Document对象
    9月22日上午JavaScript----window对象
    9月20日下午JavaScript函数--递归
    9月20日上午JavaScript函数
    9月19日下午JavaScript数组冒泡排列和二分法
    9月19日上午JavaScript数组
    9月6日表格标签(table、行、列、表头)(补)
  • 原文地址:https://www.cnblogs.com/lyr-2000/p/14326298.html
Copyright © 2011-2022 走看看