在一棵二叉搜索树中, 只有两个节点是被交换的. 找到这些节点并交换, 如果没有节点被交换就返回原来的树的根节点.
样例
样例1
输入: {4,5,2,1,3}
输出: {4,2,5,1,3}
解释:
给出的二叉搜索树:
4
/ \
5 2
/ \
1 3
返回:
4
/ \
2 5
/ \
1 3
样例2
输入: {1,2,5,4,3}
输出: {4,2,5,1,3}
解释:
给出的二叉搜索树:
1
/ \
2 5
/ \
4 3
返回:
4
/ \
2 5
/ \
1 3
解题思路:
使用中序遍历。设置三个节点分别用来标记遍历的前一个节点preNode,第一个逆序节点firstNode,第二个逆序节点secondNode,那么如果寻找逆序的两个节点呢?
考虑中序遍历为1, 5, 3, 4, 2。
如果preNode.val >= root.val,如节点5,3,则preNode节点即为firstNode节点,即节点5为firstNode。
如果firstNode存在 && preNode.val >= root.val,如节点4,2,则root节点即为secondNode节点,即节点2为secondNode。
这样的考虑天然的处理了相邻节点逆序的情况,例如3, 1, 4,firstNode为3,secondNode为1
/**
* Definition of TreeNode:
* public class TreeNode {
* public int val;
* public TreeNode left, right;
* public TreeNode(int val) {
* this.val = val;
* this.left = this.right = null;
* }
* }
*/
public class Solution {
/**
* @param root: the given tree
* @return: the tree after swapping
*/
public TreeNode bstSwappedNode(TreeNode root) {
// write your code here
inorder(root);
if(firstNode != null && secondNode != null){
int temp = firstNode.val;
firstNode.val = secondNode.val;
secondNode.val = temp;
}
return root;
}
TreeNode preNode = new TreeNode(Integer.MIN_VALUE); //root的前一个元素
TreeNode firstNode = null; //第一个逆序节点
TreeNode secondNode = null; //第二个逆序节点
private void inorder(TreeNode root){
if(root == null)
return;
inorder(root.left);
if(firstNode == null && preNode.val >= root.val)
firstNode = preNode;
if(firstNode != null && preNode.val >= root.val)
secondNode = root;
preNode = root;
inorder(root.right);
}
}