Recover Binary Search Tree

来源:互联网 发布:windows xp wifi支持 编辑:程序博客网 时间:2024/06/06 01:16

昨天去freewheel现场笔试,遇到一个编程题,回来才发现是leetcode的一道题目。。。

笔试题目这样描述的:

在一棵Binary Search Tree(BST)中,有二个节点被调换了。请找到这二个被调换的节点,并修复这棵BST,例如:

在树4761352中,节点7和节点2被调换了,将其调整为4261357.

leetcode题目:

Two elements of a binary search tree (BST) are swapped by mistake.

Recover the tree without changing its structure.

Note:
A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?

错误的做法

昨天简单的考虑了一下,发现会出现二种情况:

1)二个节点离的很远

2)二个节点紧邻

其实没有考虑完全(笔试时间太短了),下面是代码:(二次BST)

/** * 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:    void swap(TreeNode*a,TreeNode*b){        int tmp=a->val;        a->val=b->val;        b->val=tmp;    }    void recoverTree(TreeNode* root) {        queue<TreeNode*> q;         vector<TreeNode*> r;r.clear();        if(root==NULL) return;        q.push(root);        while(!q.empty()){            TreeNode* tmp=q.front();q.pop();            if(tmp->left!=NULL){                if(tmp->left->val<=tmp->val) q.push(tmp->left);                else r.push_back(tmp->left);            }            if(tmp->right!=NULL){                if(tmp->right->val>=tmp->val) q.push(tmp->right);                else r.push_back(tmp->right);            }        }        int n=r.size();        if(n==2){            swap(r[0],r[1]);        }        else if(n==1){            q.push(root);            while(!q.empty()){                TreeNode* tmp=q.front();q.pop();                if(tmp->left!=NULL){                    if(tmp->left->val<=tmp->val) q.push(tmp->left);                    else {swap(tmp,tmp->left);break;}                }                if(tmp->right!=NULL){                    if(tmp->right->val>=tmp->val) q.push(tmp->right);                    else {swap(tmp,tmp->right);break;}                }            }        }    }};

在leetcode没有AC,其中下面的情况就通不过: 3 null 2 null 1


正确的做法:

BST,很容易就让人想到中序遍历,采用中序遍历即可。下面是AC的代码

/** * 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:    void inorder(TreeNode* root){        if(root==NULL) return;        inorder(root->left);        if(prenode!=NULL&&prenode->val>root->val){//不符合排序树的规则了,prenode和root都不符合,首先存prenode            //要是二个临近就只会出现这一次,否则second会被调换。            if(first==NULL) first=prenode;            second=root;        }        prenode=root;        inorder(root->right);    }    void recoverTree(TreeNode* root) {        if(root==NULL) return;        inorder(root);        //找到二个调换元素,swap        int tmp=first->val;        first->val=second->val;        second->val=tmp;    }private:    TreeNode* prenode;     //前一个访问的元素    TreeNode* first;   //第一个要被调换的元素    TreeNode* second;  //第二个要被调换的元素};

思路很重要,编程技巧也不能少,多刷题。


0 0
原创粉丝点击