一【题目类别】
- 深度优先搜索
二【题目难度】
- 中等
三【题目编号】
- 99.恢复二叉搜索树
四【题目描述】
- 给你二叉搜索树的根节点 root ,该树中的 恰好 两个节点的值被错误地交换。请在不改变其结构的情况下,恢复这棵树 。
五【题目示例】
-
示例 1:
- 输入:root = [1,3,null,null,2]
- 输出:[3,1,null,null,2]
- 解释:3 不能是 1 的左孩子,因为 3 > 1 。交换 1 和 3 使二叉搜索树有效。
-
示例 2:
- 输入:root = [3,1,4,null,null,2]
- 输出:[2,1,4,null,null,3]
- 解释:2 不能在 3 的右子树中,因为 2 < 3 。交换 2 和 3 使二叉搜索树有效。
六【解题思路】
- 利用深度优先搜索的思想和二叉搜索树的特性
- 我们知道:对二叉搜索树进行中序遍历就会得到升序序列
- 所以我们利用这个特性,对其进行中序遍历,当我们获取到某两个节点值不满足从小到大的大小关系后,就记录这个节点
- 当然这里需要注意,不能简单地记录不满足要求的两个节点,首先我们记录第一个出错的节点
- 然后再记录最后一个出错的节点,这样才能保证我们不会换错
- 最后我们将其节点值交换即可
七【题目提示】
- 树上节点的数目在范围 [2, 1000] 内
- − 2 31 < = N o d e . v a l < = 2 31 − 1 -2^{31} <= Node.val <= 2^{31} - 1 −231<=Node.val<=231−1
八【时间频度】
- 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的节点个数
- 空间复杂度: O ( L o g 2 N ) O(Log_{2}N) O(Log2N),其中 N N N 是二叉树的节点个数
九【题目进阶】
- 使用 O ( n ) O(n) O(n) 空间复杂度的解法很容易实现。你能想出一个只使用 O ( 1 ) O(1) O(1) 空间的解决方案吗?
十【代码实现】
- Java语言版
package DFS;
public class p99_RecoverBinarySearchTree {
int val;
p99_RecoverBinarySearchTree left;
p99_RecoverBinarySearchTree right;
public p99_RecoverBinarySearchTree() {
}
public p99_RecoverBinarySearchTree(int val, p99_RecoverBinarySearchTree left, p99_RecoverBinarySearchTree right) {
this.val = val;
this.left = left;
this.right = right;
}
public p99_RecoverBinarySearchTree(int val) {
this.val = val;
}
public static void main(String[] args) {
p99_RecoverBinarySearchTree root = new p99_RecoverBinarySearchTree(1);
p99_RecoverBinarySearchTree left1 = new p99_RecoverBinarySearchTree(3);
p99_RecoverBinarySearchTree left2 = new p99_RecoverBinarySearchTree(2);
root.left = left1;
left1.right = left2;
recoverTree(root);
preOrder(root);
}
private static void preOrder(p99_RecoverBinarySearchTree root) {
if (root != null) {
System.out.print(root.val + " ");
preOrder(root.left);
preOrder(root.right);
}
}
private static p99_RecoverBinarySearchTree t1, t2, pre;
public static void recoverTree(p99_RecoverBinarySearchTree root) {
t1 = null;
t2 = null;
pre = null;
inOrder(root);
int temp = t1.val;
t1.val = t2.val;
t2.val = temp;
}
public static void inOrder(p99_RecoverBinarySearchTree root) {
if (root != null) {
inOrder(root.left);
if (pre != null && pre.val > root.val) {
if (t1 == null) {
t1 = pre;
}
t2 = root;
}
pre = root;
inOrder(root.right);
}
}
}
- C语言版
#include<stdio.h>
#include<stdlib.h>
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
};
struct TreeNode* t1;
struct TreeNode* t2;
struct TreeNode* pre;
void inOrder(struct TreeNode* root)
{
if (root)
{
inOrder(root->left);
if (pre != NULL && pre->val > root->val)
{
if (t1 == NULL)
{
t1 = pre;
}
t2 = root;
}
pre = root;
inOrder(root->right);
}
}
void recoverTree(struct TreeNode* root)
{
t1 = NULL;
t2 = NULL;
pre = NULL;
inOrder(root);
int temp = t1->val;
t1->val = t2->val;
t2->val = temp;
}
/*主函数省略*/
十一【提交结果】
-
Java语言版
-
C语言版