题目链接 : https://leetcode-cn.com/problems/recover-binary-search-tree/
题目描述:
二叉搜索树中的两个节点被错误地交换。
请在不改变其结构的情况下,恢复这棵树。
示例:
示例 1:
输入: [1,3,null,null,2]
1
/
3
\
2
输出: [3,1,null,null,2]
3
/
1
\
2
示例 2:
输入: [3,1,4,null,null,2]
3
/ \
1 4
/
2
输出: [2,1,4,null,null,3]
2
/ \
1 4
/
3
进阶:
使用 O(n) 空间复杂度的解法很容易实现。
你能想出一个只使用常数空间的解决方案吗?
思路:
这道题难点,是找到那两个交换节点,把它交换过来就行了.
这里我们二叉树搜索树的中序遍历(中序遍历遍历元素是递增的)
如下图所示, 中序遍历顺序是 4,2,3,1
,我们只要找到节点4
和节点1
交换顺序即可!
这里我们有个规律发现这两个节点:
第一个节点,是第一个按照中序遍历时候前一个节点大于后一个节点,我们选取前一个节点,这里指节点4
;
第二个节点,是在第一个节点找到之后, 后面出现前一个节点大于后一个节点,我们选择后一个节点,这里指节点1
;
对于中序遍历,我们有两种方法.
方法一: 迭代
方法二: 递归
详细链接 关于树遍历.
代码:
方法一:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def recoverTree(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
firstNode = None
secondNode = None
pre = TreeNode(float("-inf"))
stack = []
p = root
while p or stack:
while p:
stack.append(p)
p = p.left
p = stack.pop()
if not firstNode and pre.val > p.val:
firstNode = pre
if firstNode and pre.val > p.val:
#print(firstNode.val,pre.val, p.val)
secondNode = p
pre = p
p = p.right
firstNode.val, secondNode.val = secondNode.val, firstNode.val
java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public void recoverTree(TreeNode root) {
Deque<TreeNode> stack = new LinkedList<>();
TreeNode firstNode = null;
TreeNode secondNode = null;
TreeNode pre = new TreeNode(Integer.MIN_VALUE);
TreeNode p = root;
while (p != null || !stack.isEmpty()) {
while (p != null) {
stack.push(p);
p = p.left;
}
p = stack.pop();
if (firstNode == null && pre.val > p.val) firstNode = pre;
if (firstNode != null && pre.val > p.val) secondNode = p;
pre = p;
p = p.right;
}
int tmp = firstNode.val;
firstNode.val = secondNode.val;
secondNode.val = tmp;
}
}
思路二:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def recoverTree(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
self.firstNode = None
self.secondNode = None
self.preNode = TreeNode(float("-inf"))
def in_order(root):
if not root:
return
in_order(root.left)
if self.firstNode == None and self.preNode.val >= root.val:
self.firstNode = self.preNode
if self.firstNode and self.preNode.val >= root.val:
self.secondNode = root
self.preNode = root
in_order(root.right)
in_order(root)
self.firstNode.val, self.secondNode.val = self.secondNode.val, self.firstNode.val
java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
TreeNode firstNode = null;
TreeNode secondNode = null;
TreeNode preNode = new TreeNode(Integer.MIN_VALUE);
public void recoverTree(TreeNode root) {
in_order(root);
int tmp = firstNode.val;
firstNode.val = secondNode.val;
secondNode.val = tmp;
}
private void in_order(TreeNode root) {
if (root == null) return;
in_order(root.left);
if (firstNode == null && preNode.val > root.val) firstNode = preNode;
if (firstNode != null && preNode.val > root.val) secondNode = root;
preNode = root;
in_order(root.right);
}
}