Two elements of a binary search tree (BST) are swapped by mistake.
Recover the tree without changing its structure.
Example 1:
Input: [1,3,null,null,2] 1 / 3 2 Output: [3,1,null,null,2] 3 / 1 2
Example 2:
Input: [3,1,4,null,null,2] 3 / 1 4 / 2 Output: [2,1,4,null,null,3] 2 / 1 4 / 3
Follow up:
- A solution using O(n) space is pretty straight forward.
- Could you devise a constant space solution?
1. 偷懒方法
既然是BST,那就说明左边小于根,右边大于根。而且bst一定要想到inorder遍历,这样是递增的
用两个list,一个存node保证了结构,另一个存value待会排序,然后给node按上对应的value即可。
class Solution { List<TreeNode> nodel = new ArrayList(); List<Integer> numl = new ArrayList(); public void recoverTree(TreeNode root) { help(root); Collections.sort(numl); for(int i = 0; i < nodel.size(); i++){ nodel.get(i).val = numl.get(i); } } public void help(TreeNode root){ if(root == null) return; help(root.left); nodel.add(root); numl.add(root.val); help(root.right); return; } }
2.
还是inorder遍历,如果两个搞错的数相邻,说明只有一个逆序对。如果不相邻,说明造成了两个逆序对,需要将第一个逆序对的第一个数和第二个逆序对的第二个数交换
具体实现如上,用prev存前一个结点,first存第一个出问题的节点,second存第二个出问题节点,最后交换值
class Solution { TreeNode first = null; TreeNode second = null; public void recoverTree(TreeNode root) { inorderTraversal(root); int temp = first.val; first.val = second.val; second.val = temp; } TreeNode pre = null; private void inorderTraversal(TreeNode root) { if (root == null) { return; } inorderTraversal(root.left); /*******************************************************/ if(pre != null && root.val < pre.val) { //第一次遇到逆序对 if(first==null){ first = pre; second = root; //第二次遇到逆序对 }else{ second = root; } } pre = root; /*******************************************************/ inorderTraversal(root.right); } }
https://leetcode.wang/leetcode-99-Recover-Binary-Search-Tree.html
大佬讲的很清楚
3. morris遍历挖坑