问题描述:
Two elements of a binary search tree (BST) are swapped by mistake.
Recover the tree without changing its structure.
Note:
A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?
这道题大致的意思就是在一棵二叉搜索树中,有两个节点的位置被交换了,导致这棵二叉搜索树出现了错误,让你把它们换回去,对这棵二叉搜索树进行复原。同时,尽可能的对空间复杂度进行优化,最终可以只使用常数级的空间复杂度。
其实对二叉搜索树进行中序遍历,就相当于是在遍历一个有序数组。那么,如果只是O(n)的空间复杂度,其实还是挺简单的。我们直接中序遍历,读出所有的点,保存到list中;然后对list进行排序(因为list不是完全有序的,节点被交换了),最后再按原树的中序遍历,按顺序将list中的元素赋到树中的节点,就搞定了。下面是代码:
public void recoverTree(TreeNode root) {
if(root == null)
return;
List<Integer> tempList = new ArrayList<>();
inorderTravel(root, tempList);
Collections.sort(tempList);
inorderInit(root, tempList);
}
public void inorderTravel(TreeNode root, List<Integer> tempList) {
if(root == null)
return;
inorderTravel(root.left, tempList);
tempList.add(root.val);
inorderTravel(root.right, tempList);
}
public void inorderInit(TreeNode root, List<Integer> tempList) {
if(root == null)
return;
inorderInit(root.left, tempList);
root.val = tempList.get(0);
tempList.remove(0);
inorderInit(root.right, tempList);
}
至于常数级空间复杂度,其实想法也跟上面的解法差不多。既然我能够读出一个不完全有序数组放入一个新建的list中,那我为何不直接在这颗二叉搜索树上操作呢?我直接中序遍历,把它当成有序数组的遍历,然后用两个index来保存第一个出错的地方和第二个出错的地方,然后直接交换值(我刚开始还一直想着要交换节点的位置,结果操作过程复杂不说,代码也多,还很容易出错),不就解决了吗。下面是代码:
TreeNode firstElement = null;
TreeNode secondElement = null;
TreeNode prevElement = new TreeNode(Integer.MIN_VALUE);
public void recoverTree(TreeNode root) {
traverse(root);
int temp = firstElement.val;
firstElement.val = secondElement.val;
secondElement.val = temp;
}
private void traverse(TreeNode root) {
if (root == null)
return;
traverse(root.left);
if (firstElement == null && prevElement.val >= root.val) {
firstElement = prevElement;
}
if (firstElement != null && prevElement.val >= root.val) {
secondElement = root;
}
prevElement = root;
traverse(root.right);
}
所以,这道题其实不难,核心就是:你要把这棵二叉搜索树当成一个有序数组来看待。这道题你能够想到把二叉搜索树通过中序遍历转换为有序数组的模型,那么这道题就so easy啦~~~所以我觉得,有时遇到一些复杂的、不好处理的数据结构,我们要学会将它转换成相应的容易操作的模型,相关问题就可以迎刃而解了。
谢谢大家观看我的博客。如果有不明白的地方,或者是文中有错误的地方,欢迎指出,谢谢!如果大家喜欢我的博客,也可以给我点点赞。你们的点赞就是我的动力!