Artigo Diretório
Problema: Dois nós na árvore de pesquisa binária estão trocados incorretamente.
Restaure esta árvore sem alterar sua estrutura.
Exemplo 1:
输入: [1,3,null,null,2]
1
/
3
\
2
输出: [3,1,null,null,2]
3
/
1
\
2
Exemplo 2:
输入: [3,1,4,null,null,2]
3
/ \
1 4
/
2
输出: [2,1,4,null,null,3]
2
/ \
1 4
/
3
Avançado:
- A solução usando a complexidade de espaço O (n) é fácil de implementar.
- Você consegue pensar em uma solução que usa apenas espaço constante?
Fonte: LeetCode
Link: https://leetcode-cn.com/problems/recover-binary-search-tree Os
direitos autorais são propriedade de LeetCode . Para reimpressões comerciais, favor contatar a autorização oficial Para reimpressões não comerciais, favor indicar a fonte.
Ideia básica 1: travessia em ordem
O resultado da travessia em ordem da árvore de pesquisa binária deve ser uma seqüência ascendente, portanto, a seqüência na travessia de ordem intermediária nesta questão torna-se uma seqüência ascendente após a troca de dois elementos.
- Primeiro, execute uma travessia em ordem da árvore binária e salve a sequência de resultados da travessia em ordem
- Encontre o elemento pré antes do primeiro elemento invertido na sequência de resultados
- Pesquise do elemento anterior ao posterior. Quando um elemento temporário maior do que o elemento é encontrado, o elemento poste antes de temp é o elemento que precisa ser trocado
- Troque os dois elementos de pré e pós
A complexidade do espaço é O (n).
Defina uma matriz para salvar a ordem de travessia em ordem
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<TreeNode*> vec;
void recoverTree(TreeNode* root) {
inorder(root);
int pre = 0, i;
for(i = 1; i < vec.size(); ++i){
if(vec[i]->val > vec[pre]->val)
++pre;
else
break;
}
for(; i < vec.size(); ++i){
if(vec[i]->val > vec[pre]-> val)
break;
}
--i;
int t = vec[i]->val;
vec[i]->val = vec[pre]->val;
vec[pre]->val = t;
}
void inorder(TreeNode* root){
if(root == NULL)
return;
inorder(root->left);
vec.push_back(root);
inorder(root->right);
}
};
A complexidade do espaço é O (1):
defina duas variáveis para salvar os dois nós na ordem inversa
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void recoverTree(TreeNode* root) {
TreeNode* pre1 = NULL, *pre2 = NULL;
inorder(root, pre1, pre2);
int t = pre1->val;
pre1->val = pre2->val;
pre2->val = t;
}
void inorder(TreeNode* root, TreeNode* &pre1, TreeNode* &pre2){
if(root == NULL)
return;
inorder(root->left, pre1, pre2);
if(pre1 == NULL){
//root是根节点的情况
pre1 = root;
}
else{
if(root->val > pre1->val && (!pre2 || root->val < pre2->val)){
pre1 = root;
}
else if(pre2 == NULL){
//此时找到了第一个需要交换的节点,保存在pre2中
pre2 = pre1;
pre1 = root;
}
if((root->val < pre1->val) && (pre2) && (pre2->val > root->val)){
//此时找到了第二个需要交换的节点保存在pre1中
pre1 = root;
}
}
inorder(root->right, pre1, pre2);
}
};