一、题目
给你二叉搜索树的根节点 root
,该树中的 恰好 两个节点的值被错误地交换。请在不改变其结构的情况下,恢复这棵树。
Leetcode 99 题:https://leetcode.cn/problems/recover-binary-search-tree/
二、分析
一个二叉树搜索树,他的中序遍历一定是升序的。如果像题目中的一样,有两个节点的值被错误的交换,那么对应的中序遍历的结果中就会有一个或者两个地方出现 arr[i] > arr[i+1]
。因此我们有三步操作。
- 通过中序遍历,拿到数组
- 遍历数组,拿到一个或者两个地方的错误节点
- 最后遍历二叉树搜索树,替换到对应的错误节点即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| #include <vector> #include <algorithm>
struct Node { int val; Node* left; Node* right;
explicit Node(int v) : val(v), left(nullptr), right(nullptr) {} };
class Solution { public: void adjust_node(Node* head) { in_order(head); set_err_pos(); reserve(head, 2); }
private: void in_order(Node* head) { if (head == nullptr) { return; } in_order(head->left); vec_.emplace_back(head->val); in_order(head->right); }
void set_err_pos() { int head1 = -1; int head2 = -1; for (int i = 0; i < vec_.size()-1; i++) { if (vec_[i] > vec_[i+1]) { head2 = i+1; if (head1 == -1) { head1 = i; } else { break; } } } err_pos_.first = vec_[head1]; err_pos_.second = vec_[head2]; }
void reserve(Node* head, int count) { if (head == nullptr) { return; } if (head->val == err_pos_.first || head->val == err_pos_.second) { head->val = head->val == err_pos_.first ? err_pos_.second : err_pos_.first; count--; } if (count == 0) { return; } reserve(head->left, count); reserve(head->right, count); }
private: std::vector<int> vec_; std::pair<int, int> err_pos_; };
|
时间复杂度:O(n) 空间复杂度:O(n)