LeetCode 99. Recover Binary Search Tree
来源:互联网 发布:ubuntu 统计目录大小 编辑:程序博客网 时间:2024/05/16 12:18
1. 题目描述
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?
2. 解题思路
拿到这道题目, 经过分析, 我们知道如果这是一个数组的问题, 有两个值不满足数组递增排序, 只需要找到这两个位置, 交换他们的值就可以了。 但是这是一颗树, 不过没关系, 我们可以通过中序遍历获取他的这个递增数组哦。
3. code
class Solution {public: void recoverTree(TreeNode* root) { bool ret = search(root); if (!ret) swap(myfirst->val, mysecond->val); }private: bool search(TreeNode * root){ if (!root) return false; bool ret = search(root->left); if (ret) return true; if (last && root->val < last->val){ if (first){ myfirst = last; mysecond = root; first = false; } else{ swap(myfirst->val, root->val); return true; } } last = root; return search(root->right); } TreeNode * last = nullptr; bool first = true; TreeNode * myfirst = nullptr; TreeNode * mysecond = nullptr;};
4. 大神解法
4.1 inorder traversal 一样的处理思想
/*This question appeared difficult to me but it is really just a simple in-order traversal! I got really frustrated when other people are showing off Morris Traversal which is totally not necessary here.Let's start by writing the in order traversal:private void traverse (TreeNode root) { if (root == null) return; traverse(root.left); // Do some business traverse(root.right);}So when we need to print the node values in order, we insert System.out.println(root.val) in the place of "Do some business".What is the business we are doing here? We need to find the first and second elements that are not in order right?How do we find these two elements? For example, we have the following tree that is printed as in order traversal:6, 3, 4, 5, 2We compare each node with its next one and we can find out that 6 is the first element to swap because 6 > 3 and 2 is the second element to swap because 2 < 5.Really, what we are comparing is the current node and its previous node in the "in order traversal".Let us define three variables, firstElement, secondElement, and prevElement. Now we just need to build the "do some business" logic as finding the two elements. See the code below:*/public class Solution { TreeNode firstElement = null; TreeNode secondElement = null; // The reason for this initialization is to avoid null pointer exception in the first comparison when prevElement has not been initialized TreeNode prevElement = new TreeNode(Integer.MIN_VALUE); public void recoverTree(TreeNode root) { // In order traversal to find the two elements traverse(root); // Swap the values of the two nodes int temp = firstElement.val; firstElement.val = secondElement.val; secondElement.val = temp; } private void traverse(TreeNode root) { if (root == null) return; traverse(root.left); // Start of "do some business", // If first element has not been found, assign it to prevElement (refer to 6 in the example above) if (firstElement == null && prevElement.val >= root.val) { firstElement = prevElement; } // If first element is found, assign the second element to the root (refer to 2 in the example above) if (firstElement != null && prevElement.val >= root.val) { secondElement = root; } prevElement = root; // End of "do some business" traverse(root.right);}
4.2 morris
由于对morris 还不够了解, 先mark 一下
/*To understand this, you need to first understand Morris Traversal or Morris Threading Traversal. It take use of leaf nodes' right/left pointer to achieve O(1) space Traversal on a Binary Tree. Below is a standard Inorder Morris Traversal, referred from http://www.cnblogs.com/AnnieKim/archive/2013/06/15/morristraversal.html (a Chinese Blog, while the graphs are great for illustration)public void morrisTraversal(TreeNode root){ TreeNode temp = null; while(root!=null){ if(root.left!=null){ // connect threading for root temp = root.left; while(temp.right!=null && temp.right != root) temp = temp.right; // the threading already exists if(temp.right!=null){ temp.right = null; System.out.println(root.val); root = root.right; }else{ // construct the threading temp.right = root; root = root.left; } }else{ System.out.println(root.val); root = root.right; } } }In the above code, System.out.println(root.val);appear twice, which functions as outputing the Node in ascending order (BST). Since these places are in order, replace them with if(pre!=null && pre.val > root.val){ if(first==null){first = pre;second = root;} else{second = root;} }pre = root;each time, the pre node and root are in order as System.out.println(root.val); outputs them in order.Then, come to how to specify the first wrong node and second wrong node.When they are not consecutive, the first time we meet pre.val > root.val ensure us the first node is the pre node, since root should be traversal ahead of pre, pre should be at least at small as root. The second time we meet pre.val > root.val ensure us the second node is the root node, since we are now looking for a node to replace with out first node, which is found before.When they are consecutive, which means the case pre.val > cur.val will appear only once. We need to take case this case without destroy the previous analysis. So the first node will still be pre, and the second will be just set to root. Once we meet this case again, the first node will not be affected.Below is the updated version on Morris Traversal.*/public void recoverTree(TreeNode root) { TreeNode pre = null; TreeNode first = null, second = null; // Morris Traversal TreeNode temp = null; while(root!=null){ if(root.left!=null){ // connect threading for root temp = root.left; while(temp.right!=null && temp.right != root) temp = temp.right; // the threading already exists if(temp.right!=null){ if(pre!=null && pre.val > root.val){ if(first==null){first = pre;second = root;} else{second = root;} } pre = root; temp.right = null; root = root.right; }else{ // construct the threading temp.right = root; root = root.left; } }else{ if(pre!=null && pre.val > root.val){ if(first==null){first = pre;second = root;} else{second = root;} } pre = root; root = root.right; } } // swap two node values; if(first!= null && second != null){ int t = first.val; first.val = second.val; second.val = t; } }
0 0
- LeetCode 99. Recover Binary Search Tree
- [LeetCode]99.Recover Binary Search Tree
- [Leetcode] 99. Recover Binary Search Tree
- LeetCode --- 99. Recover Binary Search Tree
- [leetcode] 99.Recover Binary Search Tree
- leetcode 99. Recover Binary Search Tree
- Leetcode 99. Recover Binary Search Tree
- LeetCode 99. Recover Binary Search Tree
- LeetCode 99. Recover Binary Search Tree
- Leetcode 99. Recover Binary Search Tree
- LeetCode 99. Recover Binary Search Tree
- [LeetCode] 99. Recover Binary Search Tree
- leetcode-99. Recover Binary Search Tree
- LeetCode 99. Recover Binary Search Tree
- [LeetCode] 99. Recover Binary Search Tree
- leetcode 99. Recover Binary Search Tree
- leetcode 99. Recover Binary Search Tree
- [leetcode]99. Recover Binary Search Tree
- TortoiseGit配置直接访问GitLab
- Java NIO框架Netty教程(一) – Hello Netty
- HTML5 Canvas圆盘抽奖应用
- scrapy一些非常实用资料整理,与其他mongdb、django、redis、solr、tor结合使用以及用Python脚本调用等等方法
- 比较排序算法
- LeetCode 99. Recover Binary Search Tree
- openstack常见错误
- QT加载qwt开源控件库
- Mac下Android Studio crash 意外退出
- NavigationDrawer抽屉导航栏(如知乎)简析
- Android】开发优化之——调优工具:dump hprof file 查看内存情况,找到内存泄露,androidhprof
- Centos查看系统硬件信息
- android 时间类各种转换
- ZSC 1218 八进制小数