每天一道LeetCode-----二叉搜索树的某两个节点被交换位置,修正这个二叉搜索树

来源:互联网 发布:淘宝美工将来有前途么 编辑:程序博客网 时间:2024/06/05 19:38

Recover Binary Search Tree

原题链接Recover Binary Search Tree

这里写图片描述

给定一个二叉搜索树(BST),但是树中有两个节点被交换了,找到这两个节点,将其修正

二叉搜索树规则

  • 当前节点的值大于左子树的所有节点值
  • 当前节点的值小于右子树的所有节点值
  • 左右子树同样是二叉搜索树

对于二叉搜索树,如果进行中序遍历,那么得到的序列一定是递增的。而对于本题而言,如果使用中序遍历,那么序列中一定会有两个值影响到了递增关系

那么,只需要改变这两个值的位置,然后重新中序遍历一遍为所有节点重新赋值即可,空间复杂度为O(n)

代码如下

/** * 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 recoverTree(TreeNode* root){        vector<int> nums;        //先中序遍历把所有节点值找到        inOrder(root, nums);        //排序,修正节点值顺序        std::sort(nums.begin(), nums.end());        int i = 0;        //在中序遍历一遍,重新为节点赋值        recover(root, nums, i);    }private:    void inOrder(TreeNode* root, vector<int>& nums)    {        if(!root)   return;        inOrder(root->left, nums);        nums.emplace_back(root->val);        inOrder(root->right, nums);    }    void recover(TreeNode* root, vector<int>& nums, int& i)    {        if(!root)   return;        recover(root->left, nums, i);        root->val = nums[i++];        recover(root->right, nums, i);    }};

当然,为了优化空间复杂度,可以直接在中序遍历修改节点的值,假设中序遍历的结果是6,3,4,5,2,可以发现最后应该找到的节点是指向6的和指向2的节点

这两个节点不满足递增关系,因为

  • 6 >= 3,6是第一个节点指向的值
  • 5 >= 2,2是第二个节点指向的值
  • 交换两个节点指向的值

所以,为了易于比较,需要保存上一个节点,即总共需要三个指针

  • prevNode,保存上一次遍历的节点
  • firstNode,记录找到的第一个节点
  • secondNode,记录找到的第二个节点

不过对于第一个节点,它没有上一个节点,所以prevNode初始化不应该是nullptr,而是设定一个保存最小整数值的节点,即

TreeNode minNode(INT_MIN);prevNode = &minNode;

至此,只需要在中序遍历的时候对prevNodefirstNodesecondNode这三个节点进行更新

代码如下

/** * 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 recoverTree(TreeNode* root){        TreeNode minNode(INT_MIN);        //仅仅是为了不用new TreeNode(INT_MIN);        prevNode = &minNode;        firstNode = secondNode = nullptr;        recover(root);        swap(firstNode->val, secondNode->val);    }private:    void recover(TreeNode* root)    {        if(!root)   return;        recover(root->left);        //prevNode记录上一个节点        //当上一个节点的值大于当前节点值时,说明上一个节点是错误的,影响了递增        //因为递增的时候只能大的值跑到前面导致错误,所以prevNode是错误的        if(!firstNode && prevNode->val >= root->val)            firstNode = prevNode;        //当firstNode记录完后,当前节点小于前面的节点,说明当前节点是错误的        //因为递增的时候只能是小的值跑到后面导致错误,所以root是错误的        if(firstNode && prevNode->val >= root->val)            secondNode = root;        //改变上一个节点,继续寻找        prevNode = root;        recover(root->right);    }private:    TreeNode* prevNode;    TreeNode* firstNode;    TreeNode* secondNode;};

本题主要是中序遍历的问题,解决思路是在中序遍历中进行更改,两边遍历的方法比较容易想到,但是O(1)的不容易想到

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 合肥到九华山多少公里 九华山旅游攻略一日游 九华山在哪里个城市 九华山门票怎么买便宜 九华山大愿文化园 九华山大愿文化园旅游 华派雕塑 华派卫浴 华派照明 颐派欧华商务休闲汇馆 华派生物科技有限公司 广州华派儿童摄影 九华膏 九华苑 华祥苑什么档次 华苑二手房出售 天津华苑新楼盘 汤臣臻园 九厘板图片 九厘板规格 九厘板是什么 九厘板厂家 九厘板生产厂家 九厘板品牌 九厘板作用 腾飞九厘板 什么是九厘板 九厘板环保吗 什么叫九厘板 吊顶九厘板 九厘板尺寸 九厘板的尺寸 九厘板的规格 九厘板重量 细木工板 九厘板 九厘板的厚度 五合板 九原 包头市九原区邮政编码 包头九原区 包头市九原区邮编