99二叉探索ツリーの復元(中順遍歴+二重ポインタ逆順対+再帰遍歴)
2757 ワード
1、テーマの説明
ツリー内の2つのノードが誤って交換されました.
構造を変えずに、この木を復元してください.
ステップ:
O(n)空間複雑度を用いた解法は容易に実現できる.定数空間だけを使う解決策を考え出せますか?
2、例
入力:[3,1,4,null,null,2]
3 /\1 4 / 2
出力:[2,1,4,null,null,3]
2 /\1 4 / 3
3、問題解
基本思想:まずスタックの中序に基づいて二叉木を遍歴し、中序遍歴シーケンスmiddleOrderを得、それから二重ポインタに基づいてmiddleOrderシーケンスの中で逆序対swap 1とswap 2を探し、最後に再帰遍歴二叉木に基づいてswap 1とswap 2の2つのノード値を見つけて交換する.
ツリー内の2つのノードが誤って交換されました.
構造を変えずに、この木を復元してください.
ステップ:
O(n)空間複雑度を用いた解法は容易に実現できる.定数空間だけを使う解決策を考え出せますか?
2、例
入力:[3,1,4,null,null,2]
3 /\1 4 / 2
出力:[2,1,4,null,null,3]
2 /\1 4 / 3
3、問題解
基本思想:まずスタックの中序に基づいて二叉木を遍歴し、中序遍歴シーケンスmiddleOrderを得、それから二重ポインタに基づいてmiddleOrderシーケンスの中で逆序対swap 1とswap 2を探し、最後に再帰遍歴二叉木に基づいてswap 1とswap 2の2つのノード値を見つけて交換する.
#include
#include
#include
#include
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {}
};
#define inf 9999
void Init_TreeNode(TreeNode** T, vector& vec, int& pos)
{
if (vec[pos] == inf || vec.size() == 0)
*T = NULL;
else
{
(*T) = new TreeNode(0);
(*T)->val = vec[pos];
Init_TreeNode(&(*T)->left, vec, ++pos);
Init_TreeNode(&(*T)->right, vec, ++pos);
}
}
void PreOrderTraverse(TreeNode* T)
{
if (T == NULL)
return;
cout << T->val << " ";
PreOrderTraverse(T->left);
PreOrderTraverse(T->right);
}
class Solution {
public:
void recoverTree(TreeNode* root) {
// : , middleOrder
// middleOrder swap1 swap2
// swap1 swap2
if (root == NULL)
return;
vector middleOrder;
stack st;
TreeNode* p = root;
int swap1 = -1, swap2 = -1;
// , middleOrder
while (p != NULL || !st.empty())
{
while (p != NULL)
{
st.push(p);
p = p->left;
}
p = st.top();
st.pop();
middleOrder.push_back(p->val);
p = p->right;
}
// middleOrder swap1 swap2
int i = 0, j = middleOrder.size() - 1;
while (swap1 == -1 || swap2 == -1)
{
if (middleOrder[i] > middleOrder[i + 1])
swap1 = i;
else
i++;
if (middleOrder[j] < middleOrder[j - 1])
swap2 = j;
else
j--;
}
// swap1 swap2
Traverse(root, middleOrder[swap1], middleOrder[swap2]);
}
void Traverse(TreeNode* T, int swap1, int swap2)
{
if (T == NULL)
return;
if (T->val == swap1 || T->val == swap2)
T->val = T->val == swap1 ? swap2 : swap1;
Traverse(T->left, swap1, swap2);
Traverse(T->right, swap1, swap2);
}
};
int main()
{
Solution solute;
TreeNode* root = NULL;
vector vec = { 3,1,inf,inf,4,2,inf,inf,inf };
int pos = 0;
Init_TreeNode(&root, vec, pos);
solute.recoverTree(root);
PreOrderTraverse(root);
return 0;
}