Leetcode中几道二叉树题 I

一、二叉搜索树 (Binary Search Tree)

题目一:Recover Binary Search Tree

Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing its structure.

思路:利用搜查树的特性——中序遍历的结果是有序的,可以找打两个交换值,然后再重新遍历恢复原值。

class Solution {
private:
    int first, second, last;
public:
    void recoverTree(TreeNode *root) {
        if(root==NULL) return;
        first=1<<12;
        second=1<<12;
        last=-1<<12;
        findSwapNodes(root);
        recoverSwapNodes(root);
    }
    
    void recoverSwapNodes(TreeNode *root){
        if(root==NULL) return;
        recoverSwapNodes(root->left);
        if(first==root->val){
            root->val=second;
        }
        else if(second==root->val){
            root->val=first;
        }
        recoverSwapNodes(root->right);
    }
    
    void findSwapNodes(TreeNode *root){
        if(root==NULL) return;
        findSwapNodes(root->left);
        if(root->val<last){
            if(second==1<<12){ 
                second=last;
                first=root->val;
            }
            if(root->val<first) first=root->val;
        }
        last=root->val;
        findSwapNodes(root->right);
    }    
};

题目二:Convert Sorted List to Binary Search Tree

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

思路:将链表均分成两半,各递归构造根节点的左右子树。

class Solution {
public:
    TreeNode *sortedListToBST(ListNode *head) {
        if(head==NULL) return NULL;
        if(head->next==NULL) return new TreeNode(head->val);
        
        TreeNode *newhead=NULL;
        ListNode *p1, *p2;
        p2=head;
        p1=head->next; //使得p2在中间位置的前二位
        while(p1 && p1->next && p1->next->next){
            p1=p1->next->next;
            p2=p2->next;
        }
        p1=p2->next;
        p2->next=NULL;
        newhead=new TreeNode(p1->val);
        if(p1->next) newhead->right=sortedListToBST(p1->next);
        newhead->left=sortedListToBST(head); 
        return newhead;
    }
};

题目三: Convert Sorted Array to Binary Search Tree

Given an array where elements are sorted in ascending order, convert it to a height balanced BST

思路:思路同上!注意二分递归是注意边界条件。

class Solution {
public:
    TreeNode *sortedArrayToBST(vector<int> &num) {
        if(num.size()==0) return NULL;
        return sortedArrayToBST(num, 0, num.size()-1);
    }
    
    TreeNode *sortedArrayToBST(vector<int>& num, int start, int end){
        TreeNode *head=NULL;
        if(start<=end){
            int mid=(start+end)/2;
            head=new TreeNode(num[mid]);
            if(start<mid){  //边界条件
                head->left=sortedArrayToBST(num, start, mid-1);
            }
            if(mid<end){
                head->right=sortedArrayToBST(num, mid+1, end);
            }
        }
        return head;
    }
};


题目四:Unique Binary Search Trees

Given n, how many structurally unique BST's (binary search trees) that store values 1...n?

思路:这道题用BF方法会超时。其实这是一道组合问题。按照数学的方式就能求得解。

class Solution {
public:
    int numTrees(int n) {
        if(n<=0) return 0;
    
        vector<int> result;
        result.push_back(1); //n=0 退化的情况
        result.push_back(1); //n=1
    
        for(int k=2;k<=n;k++) //n>1
        {
            int sum=0;
            for(int i=1;i<=k;i++)
            {
                sum+=(result[i-1]*result[k-i]);
            }
    
            result.push_back(sum);
        }
    
        return result[n];
    }
};

题目五:Unique Binary Search Trees II

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

思路:不同于上面那道题,这里必须用枚举的方法。二分递归。这道题最开始我一直被一个weird problem缠住,我也不能理解,为啥出错。下面先贴出错误代码。

class Solution {
public:
    vector<TreeNode*> generateTrees(int low, int high){
        vector<TreeNode*> res;
        if(low<=high){
            TreeNode *root;
            vector<TreeNode*> left, right;
            for(int i=low; i<=high; i++){
                root=new TreeNode(i);
                left.clear();
                right.clear();
				left=generateTrees(low, i-1);
				right=generateTrees(i+1, high);
				if(left.size() && right.size()){
	                for(int j=0; j<left.size(); j++)
	                	for(int k=0; k<right.size(); k++){
							root->left=left[j];
							root->right=right[k];
							res.push_back(root);	
						} 
				}
				else if(left.size() || right.size()){
					for(int j=0; j<left.size(); j++){
						root->left=left[j];
						res.push_back(root);
					}
					for(int j=0; j<right.size(); j++){
						root->right=right[j];
						res.push_back(root);
					}
            	}
            	else res.push_back(root);
			}
        }
        return res;
    }
    
    vector<TreeNode *> generateTrees(int n) {
        vector<TreeNode*> res;
        if(n==0){
            res.push_back(NULL);
            return res;
        }
        return generateTrees(1, n);
    }
};
错误的原因:root的左右孩子节点被覆盖掉了。虽然以为root加入res以后就没啥事了,root本身的值没啥事,但是后面的操作改变了root左右孩子节点的值。还是对指针理解不够深刻!

class Solution {
public:
    vector<TreeNode*> generateTrees(int low, int high){
        vector<TreeNode*> res;
        if(low>high){
            res.push_back(NULL);   //添加叶子节点也是十分必要的呀!
            return res;
        }
        else{
            for(int i=low; i<=high; i++){
				vector<TreeNode*> left=generateTrees(low, i-1);
				vector<TreeNode*> right=generateTrees(i+1, high);
				TreeNode *root;
				for(int j=0; j<left.size(); j++){
                	for(int k=0; k<right.size(); k++){
                	    root=new TreeNode(i);           //root必须放在着这个循环里!
						root->left=left[j];
						root->right=right[k];
						res.push_back(root);	
					} 
				}
			}
			return res;
        }
    }
    
    vector<TreeNode *> generateTrees(int n) {
        vector<TreeNode*> res;
        if(n==0){
            res.push_back(NULL);
            return res;
        }
        return generateTrees(1, n);
    }
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值