题目中是二叉顺序树两个节点互换,那么就有5种交换可能。
- 根结点与左子树上的某个节点互换
- 根结点与右子树上的某个节点互换
- 左子树上的某个节点与右子树上的某个节点互换
- 左子树上的两个节点互换
- 右子树的两个节点互换
解决方法
- 对于互换1,找到左子树中的最大节点的值与根结点的值比较,若是左子树中的最大节点的值大于根结点的值,则两个节点的值进行交换。
- 对于互换2,同上。把左子树中的最大节点的值换成右子树中的最小节点的值,大于换成小于。
- 对于互换3,若左子树中的最大节点的值 > 根结点的值 > 右子树中的最小节点的值,左右两节点进行交换。
- 对于互换4、5,可把根结点的左右子树看成一颗新树,进行递归。
/**
* Definition for a binary tree node.
* 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) {}
* };
*/
class Solution {
public:
/* 求左子树中val最大的节点,用于和根结点比较,适用于互换1 */
void max(TreeNode* root,TreeNode* &big){
if(!root) return ;
if(root->val > big ->val){
big = root;
}
max(root->left,big);
max(root->right,big);
}
/* 求右子树中val最小的节点,用于和根结点比较 ,适用于互换2*/
void min(TreeNode* root,TreeNode* &small){
if(!root) return ;
if(root->val < small ->val){
small = root;
}
min(root->left,small);
min(root->right,small);
}
void recoverTree(TreeNode* root) {
if(!root) return;
TreeNode* r = root;
TreeNode *left = root->left ;
TreeNode *right = root->right ;
max(root->left,left);// 求左子树中val最大的节点
min(root->right,right);//求右子树中val最小的节点
//互换3,左右互换
if((left != NULL) && (right != NULL) && (root->val < left->val) && (root->val > right->val) ){
int val = left->val;
left->val = right->val;
right->val = val;
}
else if((left != NULL) && (root->val < left->val)){//互换1
int val = left->val;
left->val = root->val;
root->val = val;
}
else if( (right != NULL) && (root->val > right->val)){//互换2
int val = right->val;
right->val = root->val;
root->val = val;
}
else{//互换4和5
recoverTree(r->left);
recoverTree(r->right);
}
}
};
京公网安备 11010502036488号