Geek

博客园 首页 新随笔 联系 订阅 管理

单链表转二叉树

题目描述
给定一个单链表,其中的元素按升序排序,请将它转化成平衡二叉搜索树(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]
返回值
复制



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]
返回值
复制


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];
        
    }
    
    
};

posted on 2021-01-25 17:16  .geek  阅读(121)  评论(0编辑  收藏  举报