题意思路:

一棵二叉搜索树其中有两个节点调换了位置,使得这棵二叉树不再是搜索二叉树,请按升序输出这两个错误节点的值。(每个节点的值各不相同)。

方法一:中序遍历二叉树

先用中序遍历遍历二叉搜索树。

中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树。若二叉树为空则结束返回,否则:

(1)中序遍历左子树
(2)访问根结点
(3)中序遍历右子树
此时若得到的遍历结果有错误节点,则将结果按顺序标记,此时从左往右找那个大的数,并记录下答案,从右往左找小的那个数,并且索引值必大于前面记录下的索引,记录答案。

复杂度分析

时间复杂度:O(N),N表示二叉树节点数量,递归中序遍历所有节点,遍历整个数组。

空间复杂度:O(N),数组存储与读取数据

图文详解:

图片说明

class Solution {
public:
    void function(vector<int>& result,int &pre,TreeNode* root){
        if(root == NULL)
            return;
        function(result,pre,root->left);   //左子树的中序遍历
        if(pre == -1)
            pre = root->val; //第一个节点,保存下
        if(root->val < pre){ //如果错误节点
            result.push_back(pre);  
            result.push_back(root->val);

        }
        pre = root->val;
        function(result, pre, root->right);  //右子树的中序遍历
    }
    vector<int> findError(TreeNode* root) {
        vector<int> result;
        int pre = -1;//标记节点
        function(result,pre, root);//中序遍历
        vector<int> res;
        if(result.size() < 2)//特判若小于两个错误节点的值
            return res;
        else{
            //将结果记录
            res.push_back(result[result.size()-1]);
            res.push_back(result[0]);

            return res;
        }
    }
};

方法二:递归枚举
递归搜索得到搜索二叉树的中序遍历结果

此时若得到的遍历结果有错误节点,则将结果按顺序标记,此时从左往右找那个大的数,并记录下答案,从右往左找小的那个数,并且索引值必大于前面记录下的索引,记录答案。

复杂度分析

时间复杂度:O(N),N表示二叉树节点数量,递归中序遍历所有节点,遍历整个数组。

空间复杂度:O(N),数组存储与读取数据

/**
 * struct TreeNode {
 *    int val;
 *    struct TreeNode *left;
 *    struct TreeNode *right;
 * };
 */

class Solution {
public:

    vector<int> v;
    vector<int> res;
    int flag=0;
    void function(TreeNode* root){
        if(root==NULL) return;//若根为空则返回
        function(root->left);//遍历左子树
        if(flag==2) return;//若左右子树遍历完返回
        if(!v.empty()&&root->val<v[v.size()-1]){
            if(flag==0){
                res.push_back(root->val);//记录中序遍历
                res.push_back(v[v.size()-1]);
                flag=1;
            }else{
                res[0]=root->val;
                flag=2;
            }
        }
        if(flag==2) return;
        v.push_back(root->val);
        function(root->right);//遍历右子树
    }
    vector<int> findError(TreeNode* root) {

        function(root);
        return res;
    }
};