1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
| // @lc code=start
// Definition for a binary tree node.
// #[derive(Debug, PartialEq, Eq)]
// pub struct TreeNode {
// pub val: i32,
// pub left: Option<Rc<RefCell<TreeNode>>>,
// pub right: Option<Rc<RefCell<TreeNode>>>,
// }
//
// impl TreeNode {
// #[inline]
// pub fn new(val: i32) -> Self {
// TreeNode {
// val,
// left: None,
// right: None
// }
// }
// }
use std::cell::RefCell;
use std::rc::Rc;
impl Solution {
/// ## 解题思路
/// - 递归
/// 1. 二叉搜索树进行中序遍历时, 各节点值将保持顺序递增, 即node[i].val < node[i+1].val;
/// 2. 如果有两个节点进行了交换, 则交换的两个节点值与周围节点将不满足顺序递增的关系;
/// 假设交换前的两个节点node1, node2, 有 node1.val< node1.1.val < .. < node2.0.val < node2.val,
/// 则交换后, [(node2.val) > node1.1.val] < .. < [node2.0.val > (node1.val)]
/// 3. 所以, 中序遍历树时, 检查当前节点和前一个节点的大小关系,
/// 当出现了第一次逆序, 则记录前一个节点node1,
/// 出现第二次逆序时, 记录后一个节点node2,
/// 之后交换node1, node2的值
/// 4. 当被交换的两个节点node1, node2挨着时, 之后出现一次逆序情况,
/// 此时直接记录node1为前一个节点, node2为后一个节点, 综合3,4两种情况,
/// 则当发生逆序时, 逆序前一个节点只须更新一次, 后一个节点必须每次都更新;
pub fn recover_tree(root: &mut Option<Rc<RefCell<TreeNode>>>) {
/// 查找逆序节点对
fn find_unorder_pairs(
root: &Option<Rc<RefCell<TreeNode>>>,
prev: &mut Option<Rc<RefCell<TreeNode>>>,
unorder_pairs: &mut (Option<Rc<RefCell<TreeNode>>>, Option<Rc<RefCell<TreeNode>>>),
) {
if let Some(node) = root {
let node = node.borrow();
// 递归处理当前节点左子树
find_unorder_pairs(&node.left, prev, unorder_pairs);
// 处理当前节点
match prev {
// 出现了逆序节点
Some(prev1) if prev1.borrow().val > node.val => {
if unorder_pairs.0.is_none() {
//node1只更新一次记录
unorder_pairs.0 = prev.clone();
}
// node2每次都得更新记录
unorder_pairs.1 = root.clone();
}
_ => {}
}
*prev = root.clone();
// 递归处理当前节点左子树
find_unorder_pairs(&node.right, prev, unorder_pairs);
}
}
let mut pairs = (None, None);
find_unorder_pairs(root, &mut None, &mut pairs);
if let (Some(mut node1), Some(mut node2)) = pairs {
std::mem::swap(&mut node1.borrow_mut().val, &mut node2.borrow_mut().val);
}
}
}
// @lc code=end
|