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); } }
没有评论:
发表评论