[Leetcode] 95, 109, 111

本文介绍如何生成所有可能的二叉搜索树并探讨两种方法将有序链表转化为平衡二叉搜索树,同时提供了计算二叉树最小深度的算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

95. Unique Binary Search Trees II

Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1...n.

For example,
Given n = 3, your program should return all 5 unique BST's shown below.

   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3

Solution: 递归建树即可。

Code:

/**
 * 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<TreeNode*> generateTrees(int n) {
        if(n==0) return vector<TreeNode*>();//如果直接返回generateTrees的结果是[[]],但题目要求返回[]
        return generateTrees(1, n);
    }
private:
    vector<TreeNode*> generateTrees(int start, int end){
        vector<TreeNode*> ans;
        if(start>end){
            ans.push_back(NULL);
            return ans;
        }
        for(int i=start; i<=end; i++){
            vector<TreeNode*> leftsubtrees = generateTrees(start, i-1);
            vector<TreeNode*> rightsubtrees = generateTrees(i+1, end);
            for(int j=0; j<leftsubtrees.size(); j++){
                for(int q=0; q<rightsubtrees.size(); q++){
                    TreeNode* root = new TreeNode(i);
                    root->left = leftsubtrees[j];
                    root->right = rightsubtrees[q];
                    ans.push_back(root);
                }
            }
        }
        return ans;
    }
};


109. Convert Sorted List to Binary Search Tree

Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.

Solution(1):分治法。每次找到中点,然后将链表分为左右部分,分别求解左子树和右子树。但是因为单链表不能随机访问,因此必须通过遍历找到中点,时间复杂度是O(n^2)。

Code:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
/**
 * 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* sortedListToBST(ListNode* head) {
        if(head==NULL) return NULL;
        
        //计算list的长度
        int size = 0;
        ListNode* cur = head;
        while(cur!=NULL){ size++; cur = cur->next;}
        
        //取中点
        ListNode* mid = head;
        for(int i=0; i<size/2; i++) mid = mid->next;
        
        TreeNode* root = new TreeNode(mid->val);
        
        TreeNode* left = sortedListToBST_Half(head, size/2);
        TreeNode* right = sortedListToBST_Half(mid->next, size-size/2-1);
        
        root->left = left;
        root->right = right;
        return root;
    }
private:
    TreeNode* sortedListToBST_Half(ListNode* head, int size){
        if(size==0) return NULL;
        ListNode* mid = head;
        for(int i=0; i<size/2; i++) mid = mid->next;
        
        TreeNode* root = new TreeNode(mid->val);
        TreeNode* left = sortedListToBST_Half(head, size/2);
        TreeNode* right = sortedListToBST_Half(mid->next, size-size/2-1);
        
        root->left = left;
        root->right = right;
        return root;
    }
};

Solution(2): 因为链表无法自己找中点,因此使用递归让指针指向中点,并且在递归的过程中建树。是一种自底向上的方法,时间复杂度O(n)。

递归调用的过程如图所示:


可以看出,这种方法模拟了一次数据为1-n(代表下标)的二叉树的中序遍历,在遍历的过程中进行建树,同时改变list指针的位置,令其恰好指向跟节点的位置。

Code:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
/**
 * 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* sortedListToBST(ListNode* head) {
        if(head==NULL) return NULL;
        
        //计算list的长度
        int size = 0;
        ListNode* cur = head;
        while(cur!=NULL){ size++; cur = cur->next;}
        
        cur = head;
        return sortedListToBST(cur, 1, size);
    }
private:
    TreeNode* sortedListToBST(ListNode*& list, int begin, int end){
        if(begin>end) return NULL;
        
        int middle = begin + (end-begin+1)/2; //因为标准答案是在左右不均匀时,令左边多一个
        TreeNode* leftChild = sortedListToBST(list, begin, middle-1); //递归结束时list指针指向中点
        TreeNode* root = new TreeNode(list->val);
        root->left = leftChild;
        list = list->next;
        TreeNode* rightChild = sortedListToBST(list, middle+1, end);
        root->right = rightChild;
        return root;
    }
};



111. Minimum Depth of Binary Tree

Given a binary tree, find its minimum depth.

The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.

Code(递归版):

/**
 * 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 minDepth(TreeNode* root) {
        if(root==NULL) return 0;
        int mind = INT_MAX;
        getDepth(root, 1, mind);
        return mind;
    }
private:
    void getDepth(TreeNode* root, int d, int& mind){
        //假定root非空
        if(root->left==NULL && root->right==NULL){
            if(d<mind) mind = d;
            return;
        }
        if(root->left!=NULL)
            getDepth(root->left, d+1, mind);
        if(root->right!=NULL)
            getDepth(root->right, d+1, mind);
        
    }
};

Code(迭代版): 

/**
 * 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 minDepth(TreeNode* root) {
        if(root==NULL) return 0;
        
        stack<pair<TreeNode*,int>> s;//使用结构pair
        s.push(make_pair(root,1));//pair构造
        int curh;
        int minH = INT_MAX;
        TreeNode* cur = NULL;
        while(!s.empty()){
            cur = s.top().first; //pair取值
            curh = s.top().second; 
            s.pop();
            if(cur->left==NULL && cur->right==NULL){
                if(curh<minH) minH = curh;
                continue;
            }
            if(cur->left!=NULL){
                s.push(make_pair(cur->left,curh+1));
            }
            if(cur->right!=NULL){
                s.push(make_pair(cur->right,curh+1));
            }
        }
        return minH;
    }
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值