二叉树中任意两个节点之间路径的异或
给定一棵具有不同节点和一对两个节点的二叉树。任务是找到给定两个节点之间路径上的所有节点的异或。
例如,在上面的二叉树中,节点(3, 5)的路径异或将是 (3 XOR 1 XOR 0 XOR 2 XOR 5) = 5。
这个想法是利用 XOR 的这两个属性:
- 相同元素的异或为零。
- 元素与零的 XOR 给出元素本身。
现在,对于每个节点,沿着从根到该节点的路径查找并存储 XOR。这可以使用简单的 DFS 来完成。现在沿任意两个节点之间路径的 XOR 将是:
(XOR of path from root to first node) XOR (XOR of path from root to second node)
解释:出现了两种不同的情况:
- 如果这两个节点在根节点的不同子树中。那是左子树中的一个,右子树中的另一个。在这种情况下,很明显,上面编写的公式将给出正确的结果,因为节点之间的路径通过所有不同节点的根。
- 如果节点在同一个子树中。那是在左子树或右子树中。在这种情况下,您需要观察从根到两个节点的路径将有一个交点,在该交点之前,从根开始的两个节点的路径是共同的。该公共路径的 XOR 被计算两次并被抵消,因此它不影响结果。
注意:对于单对节点,不需要存储从根到所有节点的路径。考虑到是否存在节点对列表,并且对于每一对节点,我们必须在二叉树中找到两个节点之间路径的异或,这是有效且书面的。
下面是上述方法的实现:
C++
// C++ program to find XOR of path between
// any two nodes in a Binary Tree
#include
using namespace std;
// structure of a node of binary tree
struct Node {
int data;
Node *left, *right;
};
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
struct Node* getNode(int data)
{
struct Node* newNode = new Node;
newNode->data = data;
newNode->left = newNode->right = NULL;
return newNode;
}
// Function to store XOR of path from
// root to every node
// mp[x] will store XOR of path from root to node x
void storePath(Node* root, unordered_map& mp, int XOR)
{
// if root is NULL
// there is no path
if (!root)
return;
mp.insert(make_pair(root->data, XOR ^ root->data));
XOR ^= root->data;
if (root->left)
storePath(root->left, mp, XOR);
if (root->right)
storePath(root->right, mp, XOR);
}
// Function to get XOR of nodes between any two nodes
int findXORPath(unordered_map mp, int node1, int node2)
{
return mp[node1] ^ mp[node2];
}
// Driver Code
int main()
{
// binary tree formation
struct Node* root = getNode(0);
root->left = getNode(1);
root->left->left = getNode(3);
root->left->left->left = getNode(7);
root->left->right = getNode(4);
root->left->right->left = getNode(8);
root->left->right->right = getNode(9);
root->right = getNode(2);
root->right->left = getNode(5);
root->right->right = getNode(6);
int XOR = 0;
unordered_map mp;
int node1 = 3;
int node2 = 5;
// Store XOR path from root to every node
storePath(root, mp, XOR);
cout << findXORPath(mp, node1, node2);
return 0;
}
Java
// Java program to find XOR of path between
// any two nodes in a Binary Tree
import java.util.*;
class Solution
{
// structure of a node of binary tree
static class Node {
int data;
Node left, right;
}
/* Helper function that allocates a new node with the
given data and null left and right pointers. */
static Node getNode(int data)
{
Node newNode = new Node();
newNode.data = data;
newNode.left = newNode.right = null;
return newNode;
}
// Function to store XOR of path from
// root to every node
// mp[x] will store XOR of path from root to node x
static void storePath(Node root, Map mp, int XOR)
{
// if root is null
// there is no path
if (root==null)
return;
mp.put(root.data, XOR ^ root.data);
XOR ^= root.data;
if (root.left!=null)
storePath(root.left, mp, XOR);
if (root.right!=null)
storePath(root.right, mp, XOR);
}
// Function to get XOR of nodes between any two nodes
static int findXORPath(Map mp, int node1, int node2)
{
return mp.get(node1) ^ mp.get(node2);
}
// Driver Code
public static void main(String args[])
{
// binary tree formation
Node root = getNode(0);
root.left = getNode(1);
root.left.left = getNode(3);
root.left.left.left = getNode(7);
root.left.right = getNode(4);
root.left.right.left = getNode(8);
root.left.right.right = getNode(9);
root.right = getNode(2);
root.right.left = getNode(5);
root.right.right = getNode(6);
int XOR = 0;
Map mp= new HashMap();
int node1 = 3;
int node2 = 5;
// Store XOR path from root to every node
storePath(root, mp, XOR);
System.out.println( findXORPath(mp, node1, node2));
}
}
//contributed by Arnab Kundu
Python3
# Python3 program to find XOR of path between
# any two nodes in a Binary Tree
# Tree node
class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
# Helper function that allocates a node with the
# given data and None left and right pointers.
def getNode(data):
newNode = Node(0)
newNode.data = data
newNode.left = newNode.right = None
return newNode
mp = dict()
# Function to store XOR of path from
# root to every node
# mp[x] will store XOR of path from root to node x
def storePath( root, XOR) :
global mp
# if root is None
# there is no path
if (root == None) :
return
mp[root.data] = XOR ^ root.data;
XOR = XOR ^ root.data
if (root.left != None):
storePath(root.left, XOR)
if (root.right != None) :
storePath(root.right, XOR)
# Function to get XOR of nodes between any two nodes
def findXORPath( node1, node2) :
global mp
return mp.get(node1,0) ^ mp.get(node2,0)
# Driver Code
# binary tree formation
root = getNode(0)
root.left = getNode(1)
root.left.left = getNode(3)
root.left.left.left = getNode(7)
root.left.right = getNode(4)
root.left.right.left = getNode(8)
root.left.right.right = getNode(9)
root.right = getNode(2)
root.right.left = getNode(5)
root.right.right = getNode(6)
XOR = 0
node1 = 3
node2 = 5
# Store XOR path from root to every node
storePath(root, XOR)
print( findXORPath( node1, node2))
# This code is contributed by Arnab Kundu
C#
// C# program to find XOR of path between
// any two nodes in a Binary Tree
using System;
using System.Collections.Generic;
class GFG
{
// structure of a node of binary tree
class Node
{
public int data;
public Node left, right;
}
/* Helper function that allocates
a new node with the given data and
null left and right pointers. */
static Node getNode(int data)
{
Node newNode = new Node();
newNode.data = data;
newNode.left = newNode.right = null;
return newNode;
}
// Function to store XOR of path from
// root to every node
// mp[x] will store XOR of path from root to node x
static void storePath(Node root,
Dictionary mp, int XOR)
{
// if root is null
// there is no path
if (root == null)
return;
mp.Add(root.data, XOR ^ root.data);
XOR ^= root.data;
if (root.left != null)
storePath(root.left, mp, XOR);
if (root.right != null)
storePath(root.right, mp, XOR);
}
// Function to get XOR of nodes between any two nodes
static int findXORPath(Dictionary mp,
int node1, int node2)
{
return mp[node1] ^ mp[node2];
}
// Driver Code
public static void Main()
{
// binary tree formation
Node root = getNode(0);
root.left = getNode(1);
root.left.left = getNode(3);
root.left.left.left = getNode(7);
root.left.right = getNode(4);
root.left.right.left = getNode(8);
root.left.right.right = getNode(9);
root.right = getNode(2);
root.right.left = getNode(5);
root.right.right = getNode(6);
int XOR = 0;
Dictionary mp = new Dictionary();
int node1 = 3;
int node2 = 5;
// Store XOR path from root to every node
storePath(root, mp, XOR);
Console.WriteLine( findXORPath(mp, node1, node2));
}
}
/* This code is contributed PrinciRaj1992 */
Javascript
输出:
5
时间复杂度:O(N)
辅助空间:O(N),其中 N 是节点数。