import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List; /**
* Source : https://oj.leetcode.com/problems/recover-binary-search-tree/
*
*
* 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?
*
* confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ.
*
* OJ's Binary Tree Serialization:
*
* The serialization of a binary tree follows a level order traversal, where '#' signifies
* a path terminator where no node exists below.
*
* Here's an example:
*
* 1
* / \
* 2 3
* /
* 4
* \
* 5
*
* The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}".
*/
public class RecoverBinarySearchTree { private TreeNode n1;
private TreeNode n2;
private TreeNode pre; /**
* 搜索二叉树
* 将错误调换位置的两个元素恢复位置
*
* 先中序遍历树,将节点的value放到一个数组中,并将节点也放到一个数组中
* 然后将value数组排序
* 然后依次赋值给节点数组中每个节点,然后将节点数组恢复成一棵树
* 占用空间为O(n)
*
* @param root
* @return
*/
public TreeNode recover (TreeNode root) {
List<Integer> arr = new ArrayList<Integer>();
List<TreeNode> treeList = new ArrayList<TreeNode>();
traverseInorder(root, arr, treeList);
Collections.sort(arr);
for (int i = 0; i < arr.size(); i++) {
treeList.get(i).value = arr.get(i);
}
return root; } public void traverseInorder (TreeNode root, List<Integer> arr, List<TreeNode> treeList) {
if (root == null) {
return ;
}
traverseInorder(root.leftChild, arr, treeList);
arr.add(root.value);
treeList.add(root);
traverseInorder(root.rightChild, arr, treeList);
} /**
* 二叉搜索树:中序遍历的时候是单调递增的
*
* 中序遍历树,将树遍历为一个链表,当前节点的值一定大于上一个节点的值,否则就是被调换的节点,中序遍历的时候记录调换的两个节点
* 因为只有两个节点被置换,所以如果是第一次出现上一个节点的值大于当前节点,说明是被换到其前面的节点,所以被置换的是上一个节点
* 如果是第二次出现上一个节点的值大于当前节点,那么当前节点是被置换的节点
* 中序遍历完成后,调换记录的两个节点的值,就恢复了二叉搜索树
*
* @param root
* @return
*/
public TreeNode recoverTree (TreeNode root) {
traverseInorder(root);
if (n1 != null && n2 != null) {
int temp = n1.value;
n1.value = n2.value;
n2.value = temp;
}
return root;
} public void traverseInorder (TreeNode root) {
if (root == null) {
return;
}
traverseInorder(root.leftChild);
if (pre != null) {
if (pre.value > root.value) {
if (n1 == null) {
n1 = pre;
}
n2 = root;
}
}
pre = root;
traverseInorder(root.rightChild);
} public TreeNode createTree (char[] treeArr) {
TreeNode[] tree = new TreeNode[treeArr.length];
for (int i = 0; i < treeArr.length; i++) {
if (treeArr[i] == '#') {
tree[i] = null;
continue;
}
tree[i] = new TreeNode(treeArr[i]-'0');
}
int pos = 0;
for (int i = 0; i < treeArr.length && pos < treeArr.length-1; i++) {
if (tree[i] != null) {
tree[i].leftChild = tree[++pos];
if (pos < treeArr.length-1) {
tree[i].rightChild = tree[++pos];
}
}
}
return tree[0];
} /**
* 使用广度优先遍历将树转化为数组
*
* @param root
* @param chs
*/
public void binarySearchTreeToArray (TreeNode root, List<Character> chs) {
if (root == null) {
chs.add('#');
return;
}
List<TreeNode> list = new ArrayList<TreeNode>();
int head = 0;
int tail = 0;
list.add(root);
chs.add((char) (root.value + '0'));
tail ++;
TreeNode temp = null; while (head < tail) {
temp = list.get(head);
if (temp.leftChild != null) {
list.add(temp.leftChild);
chs.add((char) (temp.leftChild.value + '0'));
tail ++;
} else {
chs.add('#');
}
if (temp.rightChild != null) {
list.add(temp.rightChild);
chs.add((char)(temp.rightChild.value + '0'));
tail ++;
} else {
chs.add('#');
}
head ++;
} //去除最后不必要的
for (int i = chs.size()-1; i > 0; i--) {
if (chs.get(i) != '#') {
break;
}
chs.remove(i);
}
} private class TreeNode {
TreeNode leftChild;
TreeNode rightChild;
int value; public TreeNode(int value) {
this.value = value;
} public TreeNode() {
}
} public static void main(String[] args) {
RecoverBinarySearchTree recoverBinarySearchTree = new RecoverBinarySearchTree();
char[] tree = new char[]{'3','4','5','#','#','2'};
List<Character> chars = new ArrayList<Character>();
recoverBinarySearchTree.binarySearchTreeToArray(recoverBinarySearchTree.recover(recoverBinarySearchTree.createTree(tree)), chars);
System.out.println(Arrays.toString(chars.toArray(new Character[chars.size()]))); chars = new ArrayList<Character>();
recoverBinarySearchTree.binarySearchTreeToArray(recoverBinarySearchTree.recoverTree(recoverBinarySearchTree.createTree(tree)), chars);
System.out.println(Arrays.toString(chars.toArray(new Character[chars.size()])));
} }

leetcode — recover-binary-search-tree的更多相关文章

  1. LeetCode: Recover Binary Search Tree 解题报告

    Recover Binary Search Tree Two elements of a binary search tree (BST) are swapped by mistake. Recove ...

  2. [LeetCode] Recover Binary Search Tree 复原二叉搜索树

    Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...

  3. [leetcode]Recover Binary Search Tree @ Python

    原题地址:https://oj.leetcode.com/problems/recover-binary-search-tree/ 题意: Two elements of a binary searc ...

  4. [Leetcode] Recover Binary Search Tree

    Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...

  5. LeetCode: Recover Binary Search Tree [099]

    [题目] Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without cha ...

  6. [Leetcode] Recover binary search tree 恢复二叉搜索树

    Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...

  7. LeetCode Recover Binary Search Tree——二查搜索树中两个节点错误

    Two elements of a binary search tree (BST) are swapped by mistake.Recover the tree without changing ...

  8. [线索二叉树] [LeetCode] 不需要栈或者别的辅助空间,完成二叉树的中序遍历。题:Recover Binary Search Tree,Binary Tree Inorder Traversal

    既上篇关于二叉搜索树的文章后,这篇文章介绍一种针对二叉树的新的中序遍历方式,它的特点是不需要递归或者使用栈,而是纯粹使用循环的方式,完成中序遍历. 线索二叉树介绍 首先我们引入“线索二叉树”的概念: ...

  9. Leetcode 笔记 99 - Recover Binary Search Tree

    题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...

  10. [LeetCode] 99. Recover Binary Search Tree(复原BST) ☆☆☆☆☆

    Recover Binary Search Tree leetcode java https://leetcode.com/problems/recover-binary-search-tree/di ...

随机推荐

  1. windows10 docker镜像存储位置修改

    =====================================下面做法无效,无法成功启动docker=================================== 安装Docker ...

  2. vue开发(开发环境+项目搭建)

    Vue.js是一套构建用户界面的渐进式框架.与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计.Vue 的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合.另一方面,Vu ...

  3. Vue知识点总结

    1.属性名已$开头的都是内部提供的属性 2.为什么使用事件修饰符的原因:methods 只有纯粹的数据逻辑,而不是去处理 DOM 事件细节 3.v-if 如果值为false,元素在页面中不存在:值为t ...

  4. Java EE 导图

  5. django+javascrpt+python实现私有云盘

    代码稍后上,先整理下私有云盘的相关功能介绍. 1.登陆界面 2.首页展示,有个人目录.部门目录以及公司目录,针对不用的目录设置不同的权限控制. 3.个人信息展示 4.账号管理.账号信息展示 5.账号添 ...

  6. mysql 字符编码

    安装的是mysql5.6 社区版 安装之后编码设置为utf8 mysql的ini文件中 [mysql] default-character-set=utf8 [mysqld] default-char ...

  7. angular.js学习笔记(一)

    1.angular单项数据绑定 2.不要使用控制器的时候: 任何形式的DOM操作:控制器只应该包含业务逻辑.DOM操作则属于应用程序的表现层逻辑操作,向来以测试难度之高闻名于业界.把任何表现层的逻辑放 ...

  8. 【常用指令】git+服务器+数据库

    git日程操作 服务器常用操作 ①同步master git pull origin master ②创建分支 git checkout -b 分支名 ③常规操作 git diff git add 文件 ...

  9. Senparc.Weixin.MP SDK 微信公众平台开发教程(二十):使用菜单消息功能

    在<Senparc.Weixin.MP SDK 微信公众平台开发教程(十一):高级接口说明>教程中,我们介绍了如何使用“客服接口”,即在服务器后台,在任意时间向微信发送文本.图文.图片等不 ...

  10. 【安富莱二代示波器教程】第19章 附件E---参考资料

    第19章      附件E---参考资料 DSP教程 http://forum.armfly.com/forum.php?mod=viewthread&tid=3886 . FreeRTOS教 ...