📌  相关文章
📜  二叉树中任意两个节点之间路径的异或

📅  最后修改于: 2022-05-13 01:57:17.101000             🧑  作者: Mango

二叉树中任意两个节点之间路径的异或

给定一棵具有不同节点和一对两个节点的二叉树。任务是找到给定两个节点之间路径上的所有节点的异或。

例如,在上面的二叉树中,节点(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)

解释:出现了两种不同的情况:

  1. 如果这两个节点在根节点的不同子树中。那是左子树中的一个,右子树中的另一个。在这种情况下,很明显,上面编写的公式将给出正确的结果,因为节点之间的路径通过所有不同节点的根。
  2. 如果节点在同一个子树中。那是在左子树或右子树中。在这种情况下,您需要观察从根到两个节点的路径将有一个交点,在该交点之前,从根开始的两个节点的路径是共同的。该公共路径的 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 是节点数。