Two elements of a binary search tree (BST) are swapped by mistake.
Recover the tree without changing its structure.
这道题是要求恢复一颗有两个元素调换错了的二叉查找树。中序遍历BST 然后找到逆序。
1. 中序遍历相邻的两个元素被调换了,很容易想到就只需会出现一次违反情况,只需要把这个两个节点记录下来最后调换值就可以;
2. 如果是不相邻的两个元素被调换了,会发生两次逆序的情况,那么这时候需要调换的元素应该是第一次逆序前面的元素,和第二次逆序后面的元素。比如1234567,1和5调换了,会得到5234167,逆序发生在52和41,我们需要把4和1调过来,那么就是52的第一个元素,41的第二个元素调换即可。
时间复杂度是O(n),空间是栈大小O(logn)
1. 中序遍历相邻的两个元素被调换了,很容易想到就只需会出现一次违反情况,只需要把这个两个节点记录下来最后调换值就可以;
2. 如果是不相邻的两个元素被调换了,会发生两次逆序的情况,那么这时候需要调换的元素应该是第一次逆序前面的元素,和第二次逆序后面的元素。比如1234567,1和5调换了,会得到5234167,逆序发生在52和41,我们需要把4和1调过来,那么就是52的第一个元素,41的第二个元素调换即可。
时间复杂度是O(n),空间是栈大小O(logn)
public class Solution {
TreeNode pre, first, second;
public void recoverTree(TreeNode root) {
pre = null;
first = null;
second = null;
inorder(root);
if (first != null && second != null){
int tem = first.val;//只调换val 不是node
first.val = second.val;
second.val = tem;
}
}
private void inorder(TreeNode root){
if (root == null){
return;
}
inorder(root.left);
if (pre == null){
pre = root;//初始化pre
} else {
if (pre.val > root.val){
if (first == null){
first = pre;//第一个逆序点
}
second = root;//如果相邻第一次就找全, 如果不相邻则遍历完后找到第二个逆序点
}
pre = root;//给pre赋值
}
inorder(root.right);
}
}
//方法2 不用全局变量
public class Solution {
public void recoverTree(TreeNode root) {
if (root == null) {
return;
}
ArrayList<TreeNode> res = new ArrayList<TreeNode>();
ArrayList<TreeNode> tem = new ArrayList<TreeNode>();
tem.add(null);
helper(root, res, tem);
if (res.size() > 0) {
int save = res.get(0).val;
res.get(0).val = res.get(1).val;
res.get(1).val = save;
}
}
public void helper(TreeNode root, ArrayList<TreeNode> res, ArrayList<TreeNode> tem) {
if (root == null) {
return;
}
helper(root.left, res, tem);
if (tem.get(0) != null && root.val < tem.get(0).val) {
if (res.size() == 0) {
res.add(tem.get(0));
res.add(root);
} else {
res.set(1, root);
}
}
tem.set(0, root);
helper(root.right, res, tem);
}
}
没有评论:
发表评论