菜鸡每日一题系列打卡99天
每天一道算法题目
小伙伴们一起留言打卡
坚持就是胜利,我们一起努力!
题目描述(引自LeetCode)
二叉搜索树中的两个节点被错误地交换。请在不改变其结构的情况下,恢复这棵树。
示例 1:
输入: [1,3,null,null,2]
1
/
3
\
2
输出: [3,1,null,null,2]
3
/
1
\
2
示例 2:
输入: [3,1,4,null,null,2]
3
/ \
1 4
/
2
输出: [2,1,4,null,null,3]
2
/ \
1 4
/
3
进阶:
使用 O(n) 空间复杂度的解法很容易实现。
你能想出一个只使用常数空间的解决方案吗?
题目分析
这是每日一题——验证二叉搜索树的进阶版,与该题目的思路类似,我们可以采用递归或者迭代的方式进行求解。
在每日一题——验证二叉搜索树我们说过,二叉搜索树的中序遍历是一个升序序列,因此,我们只需要在递归或者迭代中序遍历的过程中,发现并记录两处逆序的结点,然后将其交换即可。
为了给大家提供不同的思路,菜鸡在本文中将采用上述两种方式进行解答。话不多说,上代码!
代码实现
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
// 迭代中序遍历
class Solution {
public void recoverTree(TreeNode root) {
TreeNode first = null, second = null, flag = null;
Stack<TreeNode> stack = new Stack<>();
while (!stack.isEmpty() || root != null) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
if (flag != null && root.val < flag.val) {
second = root;
// 第一次遇到逆序
if (first == null) first = flag;
// 第二次遇到逆序
else break;
}
flag = root;
root = root.right;
}
int tmp = first.val;
first.val = second.val;
second.val = tmp;
}
}
// 递归中序遍历
class Solution {
private TreeNode first = null, second = null, flag = null;
public void recoverTree(TreeNode root) {
findNode(root);
int tmp = first.val;
first.val = second.val;
second.val = tmp;
}
private void findNode(TreeNode root) {
if (root == null) return;
findNode(root.left);
if (flag != null && root.val < flag.val) {
second = root;
//第一次遇到逆序
if (first == null) first = flag;
//第二次遇到逆序
else return;
}
flag = root;
findNode(root.right);
}
}
代码分析
对代码进行分析,设二叉树的结点个数为n,高度为h,则:
迭代中序遍历:最坏情况下,时间复杂度为O(n),空间复杂度为O(h)。
递归中序遍历:最坏情况下,时间复杂度为O(n),空间复杂度为O(h)。
执行结果
迭代中序遍历的执行结果
递归中序遍历的执行结果
学习 | 工作 | 分享
????长按关注“有理想的菜鸡”
只有你想不到,没有你学不到