完成比完美更重要,自己动手写一些看
[99] 恢复二叉搜索树
二叉搜索树中的两个节点被错误地交换。
请在不改变其结构的情况下,恢复这棵树。
//递归遍历
class Solution {
public:
void recoverTree(TreeNode* root)
{
// 01 check
if (root == NULL) {
return;
}
// 02 dfs
TreeNode* first = NULL; //第一个元素 6>3,选择 6 【1 2 3 4 5 6】(6,2)
TreeNode* second = NULL; // 第二个元素 5>2 选择 2 【1 2 3 4 5 6】(6,2)
TreeNode* pre = NULL; // 记录上一个记录
recoverTree(root, pre, first, second);
//03 swap
if (first && second) {
int temp = first->val;
first->val = second->val;
second->val = temp;
}
}
void recoverTree(TreeNode* root, TreeNode*& pre, TreeNode*& first, TreeNode*& second)
{
if (NULL == root) {
return; //递归退出条件
}
//01 中序递归遍历
recoverTree(root->left, pre, first, second);
//here
//判断是否逆序
if (pre && pre->val > root->val) {
if (first == NULL) {
first = pre; //must
second = root;
// 【1 2 3 4 】 (2,3)
// 【1 3 2 4 】 只有3>2 ,没有第二个比较, 该怎么办 (first>second)
} else {
second = root;
// *假设有一个递增序列 a = [ 1, 2, 3, 4, 5, 6, 7 ]
// 如果我们交换两个不相邻的数字,例如 2 和 6,
// 原序列变成了 a = [ 1, 6, 3, 4, 5, 2, 7 ] ,
// first 6 > 3, second)5 > 2
}
}
//记录
pre = root;
recoverTree(root->right, pre, first, second);
}
};
//非递归遍历
class Solution {
public:
//32ms
void recoverTree(TreeNode* root)
{
//01 check
if (nullptr == root)
return;
//02 依赖stack
//非递归遍历,在一个函数内完成,不需要二级指针传递参数.保存改变
TreeNode* first = nullptr;
TreeNode* second = nullptr;
TreeNode* pre = nullptr;
vector<TreeNode*> stack; //用数组模拟栈
//stack.push_back(root); 这里插入不合适
while (stack.size() > 0 || nullptr != root) {
//遍历左子树
while (root) {
stack.push_back(root);
root = root->left; //move
}
// 走到这里说明 root ==nill
//访问节点
root = stack.back();
stack.pop_back();
//判断是否逆序
if (nullptr != pre && pre->val > root->val) {
if (nullptr == first) {
first = pre;
}
second = root;
}
pre = root; //下次访问
//遍历右子树
root = root->right;
}
//03 swap
if (first && second) {
int temp = first->val;
first->val = second->val;
second->val = temp;
}
}
};
//递归遍历
func recoverTree(root *TreeNode) {
if nil ==root {
return
}
//递归遍历,需要通过函数参数 修改另外一个函数的变量
var first *TreeNode =nil //两个节点被错误.out
var second *TreeNode =nil //两个节点被错误,out
var pre *TreeNode =nil //一个变量空间
InOrderTree(root,&pre,&first,&second) //golang 没用引用传递
first.Val, second.Val = second.Val, first.Val //修改指针内容,必须二级指针
}
func InOrderTree(root *TreeNode, pre **TreeNode,first **TreeNode, second **TreeNode) {
if nil ==root {
return
}
InOrderTree(root.Left,pre,first,second)
//默认为ni
if nil != *pre && (*pre).Val > (*root).Val {
if *first == nil {
*first =*pre
}
*second =root
}
*pre =root //
InOrderTree(root.Right,pre,first,second)
}
检查 题目是否看明白,理解有没有偏差
二叉搜索树中的两个节点被错误地交换。
请在不改变其结构的情况下,恢复这棵树。
示例 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) 空间复杂度的解法很容易实现。
你能想出一个只使用常数空间的解决方案吗?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/recover-binary-search-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思考 60秒 。。。
思考 60秒 。。
这个题目试着这里开始入手
算法五个重要的特征:
检查 思路是否清晰合理,不是靠道听途说, 别人说这样好就好,
分享最实用的经验 , 希望每一位来访的朋友都能有所收获! 如果有疑问请联系我,一起探讨,进步。