检查给定的树是否可以在 K 次交换中相互镜像
给定两个具有相同结构但可能具有不同值排列的二叉树并给定一个整数K 。任务是检查在第一棵树上完全交换K之后,它是否会成为第二棵树的镜像。在一次交换中,我们取同一父节点的两个节点并交换其左右子树。
例子:
Input: K = 1
1 1
/ \ / \
2 3 2 3
Output: Yes
Input: K = 4
11 11
/ \ / \
25 15 25 15
/ \ / \ / \ / \
7 9 10 21 10 21 9 7
Output: Yes
Explanation: Here first we need to swap two pairs (25, 15) and (10 ,21) in the first tree hence K = 2. And then we do swap of (21, 7) and (10, 9) therefore here is total of 4 swap.
方法:解决这个问题的基本方法是基于以下思想使用递归和堆栈:
The idea is to traverse the first tree and check by swapping nodes recursively, if the tree becomes mirror image of second tree.
请按照以下步骤实施上述方法:
- 在迭代中序遍历的帮助下,一一检查两棵树的所有各自节点。
- 如果发现两棵树的各自数据部分不匹配,那么我们只需增加所需交换的计数
- 遍历完成后,检查以下条件,如果以下任一条件为真,则返回 Yes:
- 如果我们的计数与K 相同,或者
- 如果 count 小于 K 并且(K – count)是偶数,
- 否则返回编号
下面是上述方法的实现:
C++
// C++ program of above approach
#include
using namespace std;
// A binary tree node has data,
// pointer to left child
// and a pointer to right child
class node {
public:
int data;
node* left;
node* right;
};
// Create new node.
node* newNode(int data)
{
node* Node = new node();
Node->data = data;
Node->left = NULL;
Node->right = NULL;
return (Node);
}
// Function to convert tree
// into its mirror tree
void convert(node* root)
{
if (!root)
return;
// Recursively call left
// and right node
convert(root->left);
convert(root->right);
// Swap left and right of any node
swap(root->left, root->right);
}
// Function to check identical and
// count no of swap needed to be
int checkIdentical(node* p, node* q)
{
stack st1, st2;
int count = 0;
while (p || !st1.empty()
&& q || !st2.empty()) {
// If p q are not
// null push in stack
if (p && q) {
st1.push(p);
st2.push(q);
// Send p and q
// to its left child
p = p->left;
q = q->left;
}
// If p and q are null
// pop node from stack
else {
p = st1.top();
q = st2.top();
st1.pop();
st2.pop();
// If data not match
// increment count
if (p->data != q->data)
count++;
// Send p and q to
// its right child
p = p->right;
q = q->right;
}
}
// Return count/2 because
// we swap pairs
return count / 2;
}
/* Driver code*/
int main()
{
node* root1 = newNode(11);
root1->left = newNode(25);
root1->right = newNode(15);
root1->left->left = newNode(7);
root1->left->right = newNode(9);
root1->right->left = newNode(10);
root1->right->right = newNode(21);
node* root2 = newNode(11);
root2->left = newNode(25);
root2->right = newNode(15);
root2->left->left = newNode(10);
root2->left->right = newNode(21);
root2->right->left = newNode(9);
root2->right->right = newNode(7);
int K = 4;
// First convert first
// tree into mirror tree
convert(root1);
int count = checkIdentical(root1, root2);
if (count <= K
&& (K - count) % 2 == 0)
cout << "Yes" << endl;
else
cout << "No" << endl;
return 0;
}
Yes
时间复杂度: O(N)
辅助空间: O(N)