leetcode99 修复二叉树

52 阅读1分钟

给你二叉搜索树的根节点 root ,该树中的 恰好 两个节点的值被错误地交换。请在不改变其结构的情况下,恢复这棵树

  1. 第一种解决方法,就是使用一个数组进行存放中序遍历的结点,然后找到错误的两个结点交换二者的值。代码如下:
public void recoverTree(TreeNode root) {
     List<TreeNode> result = new ArrayList<>();
     dfsBST(root,result);
     TreeNode wrongNode1 = null;
     TreeNode wrongNode2 = null;
     for (int i = 1; i < result.size(); i++) {
         if (result.get(i).val < result.get(i-1).val){
             wrongNode2 = result.get(i);
             if (wrongNode1 == null) wrongNode1 = result.get(i-1);
         }
     }
     if (wrongNode1 != null && wrongNode2 !=null){
         int exchange = wrongNode1.val;
         wrongNode1.val = wrongNode2.val;
         wrongNode2.val = exchange;
     }
 }
 private void dfsBST(TreeNode treeNode, List<TreeNode> result){
     if(treeNode == null) return;
     dfsBST(treeNode.left,result);
     result.add(treeNode);
     dfsBST(treeNode.right,result);
 }

该算法使用了o(n)的时间复杂度,以及O(n)的空间复杂度。

  1. 第二种解决方法是使用递归隐式或者遍历维持显式栈,来进行元素的存放。代码如下:
private TreeNode pre = null;
 private TreeNode wrongNode1 = null;
 private TreeNode wrongNode2 = null;
public void recoverTree(TreeNode root) {
 dfsBST(root);
 if(wrongNode1 != null && wrongNode2 != null){
     Integer exchange = wrongNode1.val;
     wrongNode1.val = wrongNode2.val;
     wrongNode2.val = exchange;
 }
}
 private void dfsBST(TreeNode treeNode){
     if(treeNode == null) return;
     dfsBST(treeNode.left);
     if (pre != null && pre.val < treeNode.val){
         wrongNode2 = treeNode;
         if(wrongNode1 == null) wrongNode1 = pre;
     }
         pre = treeNode;
     dfsBST(treeNode.right);
 }

该算法的时间复杂度为O(n),空间复杂度为O(h) h为递归或者遍历时BST的树的高度。

  1. 但是该题目要求需要使用O(1)的空间的算法,那么就需要进行使用莫里斯遍历,该算法比较难,而且实用性不是特别强。就需要简单的了解就行了。