XOR of path between any two nodes in a Binary Tree

Given a binary tree with distinct nodes and a pair of two nodes. The task is to find the XOR of all of the nodes which comes on the path between the given two nodes.

For Example, in the above binary tree for nodes (3, 5) XOR of path will be (3 XOR 1 XOR 0 XOR 2 XOR 5) = 5.

The idea is to make use of these two properties of XOR:

Now, for each node find and store the XOR along the path from root to that node. This can be done using simple DFS. Now the XOR along path between any two nodes will be:



(XOR of path from root to first node) XOR (XOR of path from root to second node)

Explanation: There arises two different cases:

  1. If the two nodes are in different subtrees of root nodes. That is one in the left subtree and the other in the right subtree. In this case it is clear that the formulae written above will give the correct result as the path between the nodes goes through root with all distinct nodes.
  2. If the nodes are in the same subtree. That is either in the left subtree or in the right subtree. In this case you need to observe that path from root to the two nodes will have an intersection point before which the path is common for the two nodes from root. The XOR of this common path is calculated twice and cancels out, so it does not effect the result.

Note: For a single pair of nodes, it is not needed to store the path from roots to all nodes. This is efficient and written considering if there is a list of pair of nodes and for every pair we have to find XOR of path between the two nodes in a Binary Tree.

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find XOR of path between
// any two nodes in a Binary Tree
#include <bits/stdc++.h>
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<int, int>& 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<int, int> 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<int, int> 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;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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<Integer, Integer> 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<Integer, Integer> 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<Integer, Integer> mp= new HashMap<Integer, Integer>(); 
  
    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
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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<int, int> 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<int, int> 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<int, int> mp = new Dictionary<int, int>(); 
  
        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 */
chevron_right

Output:
5

Time Complexity: O(N)
Auxiliary Space: O(N), where N is the number of nodes.

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.





Striver(underscore)79 at Codechef and codeforces D

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : andrew1234, princiraj1992

Article Tags :
Practice Tags :