From 2a7bcd1cbcdaddbf1ca912b8caa807f3c3303e6f Mon Sep 17 00:00:00 2001 From: Dipanita45 <132455672+Dipanita45@users.noreply.github.com> Date: Mon, 28 Oct 2024 18:58:05 +0530 Subject: [PATCH] Added the algorithm --- .../Leaf Similar Tree/Program.c | 72 +++++++++++++++++++ .../Leaf Similar Tree/Readme.md | 46 ++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 Backtracking Algorithms/Leaf Similar Tree/Program.c create mode 100644 Backtracking Algorithms/Leaf Similar Tree/Readme.md diff --git a/Backtracking Algorithms/Leaf Similar Tree/Program.c b/Backtracking Algorithms/Leaf Similar Tree/Program.c new file mode 100644 index 00000000..bafbecb1 --- /dev/null +++ b/Backtracking Algorithms/Leaf Similar Tree/Program.c @@ -0,0 +1,72 @@ +// C++ code to check if leaf traversals +// of two Binary Trees are same or not. +#include +using namespace std; + +// Binary Tree Node +struct Node { + int data; + Node* left; + Node* right; +}; + +// Returns new Node with data as +// input to below function. +Node* newNode(int d) +{ + Node* temp = new Node; + temp->data = d; + temp->left = NULL; + temp->right = NULL; + + return temp; +} + +// Function to store the leaf nodes of the tree +void collectLeafNodes(Node* root, vector& storeLeaf) +{ + if (!root->left && !root->right) { + storeLeaf.push_back(root->data); + } + if (root->left) { + collectLeafNodes(root->left, storeLeaf); + } + if (root->right) { + collectLeafNodes(root->right, storeLeaf); + } +} + +// iterative function. +// returns true if leaf traversals +// are same, else false. +bool isSame(Node* root1, Node* root2) +{ + vector storeLeafTree1, storeLeafTree2; + collectLeafNodes(root1, storeLeafTree1); + collectLeafNodes(root2, storeLeafTree2); + return storeLeafTree1 == storeLeafTree2; +} + +// Driver Code +int main() +{ + Node* root1 = newNode(1); + root1->left = newNode(2); + root1->right = newNode(3); + root1->left->left = newNode(4); + root1->right->left = newNode(6); + root1->right->right = newNode(7); + + Node* root2 = newNode(0); + root2->left = newNode(1); + root2->right = newNode(5); + root2->left->right = newNode(4); + root2->right->left = newNode(6); + root2->right->right = newNode(7); + + if (isSame(root1, root2)) + cout << "Same"; + else + cout << "Not Same"; + return 0; +} \ No newline at end of file diff --git a/Backtracking Algorithms/Leaf Similar Tree/Readme.md b/Backtracking Algorithms/Leaf Similar Tree/Readme.md new file mode 100644 index 00000000..b1127eaa --- /dev/null +++ b/Backtracking Algorithms/Leaf Similar Tree/Readme.md @@ -0,0 +1,46 @@ +## Leaf-Similar Tree + +# Problem Description +In the given problem, we are asked to compare two binary trees to check if they are 'leaf-similar'. Binary trees are a type of data structure in which each node has at most two children, referred to as the left child and the right child. A leaf node is a node with no children. The 'leaf value sequence' is the list of values of these leaf nodes read from left to right. Two binary trees are considered 'leaf-similar' if the sequences of their leaf values are identical. + +# Solution Approach +The solution is implemented in Python, and it focuses on a Depth-First Search (DFS) approach to traverse through the binary trees. The implementation defines a nested function dfs within the leafSimilar method, with the purpose of performing the actual DFS traversal, searching the entire tree for its leaves, and building the leaf sequence. + +Here's the step-by-step breakdown of the algorithm: + +The dfs function is defined, which takes a single argument, root, representing the current node in the tree. +Upon each invocation of dfs, the function first checks if the current root node is None. If it is, it returns an empty list as there are no leaves to gather from a None subtree. +If the current node is not None, the dfs function first recursively calls itself with root.left and root.right to search through the entire left and right subtrees. +The leaves are gathered by this part of the code: ans = dfs(root.left) + dfs(root.right). This code concatenates the left and right subtree leaves into one sequence. +Finally, the function checks if the node is a leaf node, that means both root.left and root.right are None. If it is a leaf, it returns a list containing the leaf's value: [root.val]. If the node is not a leaf, it returns the concatenated list of leaf values from both the left and right subtrees. +The main function leafSimilar calls the dfs function for both root1 and root2 trees, collecting the sequences of leaf values as lists. +The solution concludes by comparing these two lists with dfs(root1) == dfs(root2). If they are identical, it means that the leaf value sequences are the same, and therefore the two trees are considered leaf-similar and True is returned. If the sequences differ in any way, the function returns False. + +# Examples: + +Input: Roots of below Binary Trees + 1 + / \ + 2 3 + / / \ + 4 6 7 + + 0 + / \ + 5 8 + \ / \ + 4 6 7 +Output: same +Leaf order traversal of both trees is 4 6 7 + +Input: Roots of below Binary Trees + 0 + / \ + 1 2 + / \ + 8 9 + +# Time Complexity and Space Complexity +The time complexity of the algorithm is determined by the depth-first search (DFS) function, which visits every node in the binary tree exactly once. Therefore, the time complexity is O(N+M), where N is the number of nodes in the first tree and M is the number of nodes in the second tree. + +The space complexity is mainly governed by the call stack of the recursive DFS calls and the space used to store the leaf values. In the worst case, the depth of the recursion could be O(H1+H2), where H1 is the maximum height of the first tree and H2 is the maximum height of the second tree, if the trees are highly skewed. \ No newline at end of file