0% found this document useful (0 votes)
3 views28 pages

Winter Camp 5

Uploaded by

Saptadip Das
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views28 pages

Winter Camp 5

Uploaded by

Saptadip Das
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 28

DEPARTMENT OF

COMPUTER SCIENCE & ENGINEERING

Daily Assignment – 27th Dec 2024

Student Name: Ramaz UID: 22BCS16271


Branch: BE-CSE Section/Group: FL-IOT_604 / A
Subject Name: Winter Winning Camp Date of Performance: Dec 27, 2024

VERY EASY
1. Binary Tree Inorder Traversal

Given the root of a binary tree, return the inorder traversal of its nodes' values.

Example 1:
Input: root = [1,null,2,3]
Output: [1,3,2]
Explanation:

Example 2:
Input: root = [1,2,3,4,5,null,8,null,null,6,7,9]
Output: [4,2,6,5,7,1,3,9,8]
Explanation:

8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

Constraints:
The number of nodes in the tree is in the range [0, 100].
-100 <= Node.val <= 100

CODE:
#include <iostream>
#include <vector>
#include <queue>
#include <sstream>

using namespace std;

// Definition for a binary tree node.


struct Node {
int value;
Node *left;
Node *right;
Node(int x) : value(x), left(nullptr), right(nullptr) {}
};

// Function to perform inorder traversal


void inorderTraversal(Node* root, vector<int>& result) {
if (root == nullptr) {
return;
}
inorderTraversal(root->left, result); // Visit left subtree
result.push_back(root->value); // Visit root
inorderTraversal(root->right, result); // Visit right subtree
}

// Function to create a binary tree from input


Node* buildBinaryTree(const vector<string>& nodeValues) {
if (nodeValues.empty() || nodeValues[0] == "null") {
return nullptr;
}

Node* root = new Node(stoi(nodeValues[0]));


queue<Node*> nodesQueue;
nodesQueue.push(root);
int idx = 1;

while (!nodesQueue.empty() && idx < nodeValues.size()) {


Node* currentNode = nodesQueue.front();
nodesQueue.pop();

8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
// Create left child
if (idx < nodeValues.size() && nodeValues[idx] != "null") {
currentNode->left = new Node(stoi(nodeValues[idx]));
nodesQueue.push(currentNode->left);
}
idx++;

// Create right child


if (idx < nodeValues.size() && nodeValues[idx] != "null") {
currentNode->right = new Node(stoi(nodeValues[idx]));
nodesQueue.push(currentNode->right);
}
idx++;
}

return root;
}

int main() {
string input;
cout << "Enter the binary tree nodes in level order (use 'null' for empty nodes, space-separated): ";
getline(cin, input);

// Split the input string into a vector


stringstream ss(input);
vector<string> nodeValues;
string node;
while (ss >> node) {
nodeValues.push_back(node);
}

Node* root = buildBinaryTree(nodeValues); // Create the binary tree


vector<int> traversalResult; // Vector to store the inorder traversal result

inorderTraversal(root, traversalResult); // Perform inorder traversal

// Output the result


cout << "Inorder traversal: ";
for (int value : traversalResult) {
cout << value << " ";
}
cout << endl;
return 0;
}

8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
OUTPUT:

2. Binary Tree - Find Maximum Depth

A binary tree's maximum depth is the number of nodes along the longest path from the root node down to
the farthest leaf node.

Example 1:
Input: [3,9,20,null,null,15,7]
Output: 3

Example 2:
Input: [1,null,2]
Output: 2

Constraints:
The number of nodes in the tree is in the range [0, 104].
-100 <= Node.val <= 100

CODE:
#include <iostream>
#include <vector>
#include <queue>
#include <sstream>
using namespace std;

// Definition for a binary tree node.


struct Node {
int data;
Node *left;
Node *right;
Node(int value) : data(value), left(nullptr), right(nullptr) {}
};

// Function to calculate the maximum depth of the binary tree


int getMaxDepth(Node* root) {
if (root == nullptr) {
return 0; // Base case: if the tree is empty, depth is 0
}
// Recursively find the depth of the left and right subtrees and add 1 for the root
return 1 + max(getMaxDepth(root->left), getMaxDepth(root->right));
}

// Function to create a binary tree from input


8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
Node* constructBinaryTree(const vector<string>& nodeValues) {
if (nodeValues.empty() || nodeValues[0] == "null") {
return nullptr;
}

Node* root = new Node(stoi(nodeValues[0]));


queue<Node*> nodeQueue;
nodeQueue.push(root);
int index = 1;

while (!nodeQueue.empty() && index < nodeValues.size()) {


Node* currentNode = nodeQueue.front();
nodeQueue.pop();

// Create left child


if (index < nodeValues.size() && nodeValues[index] != "null") {
currentNode->left = new Node(stoi(nodeValues[index]));
nodeQueue.push(currentNode->left);
}
index++;

// Create right child


if (index < nodeValues.size() && nodeValues[index] != "null") {
currentNode->right = new Node(stoi(nodeValues[index]));
nodeQueue.push(currentNode->right);
}
index++;
}

return root;
}

int main() {
string input;
cout << "Enter the binary tree nodes in level order (use 'null' for empty nodes, space-separated): ";
getline(cin, input);

// Split the input string into a vector


stringstream ss(input);
vector<string> nodeValues;
string value;
while (ss >> value) {
nodeValues.push_back(value);
}

Node* root = constructBinaryTree(nodeValues); // Create the binary tree


8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
int maxDepth = getMaxDepth(root); // Calculate the maximum depth

// Output the result


cout << "Maximum depth of the binary tree: " << maxDepth << endl;

return 0;
}

OUTPUT:

3. Binary Tree Preorder Traversal

Given the root of a binary tree, return the preorder traversal of its nodes' values.

Example 1:
Input: root = [1,null,2,3]
Output: [1,2,3]
Explanation:

Example 2:
Input: root = [1,2,3,4,5,null,8,null,null,6,7,9]
Output: [1,2,4,5,6,7,3,8,9]
Explanation:

Constraints:
8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
The number of nodes in the tree is in the range [1, 100].
1 <= Node.val <= 1000

CODE:
#include <iostream>
#include <vector>
#include <queue>
#include <sstream>
using namespace std;

// Definition for a binary tree node.


struct Node {
int value;
Node *left;
Node *right;
Node(int x) : value(x), left(nullptr), right(nullptr) {}
};

// Function to perform preorder traversal


void preorderTraversal(Node* root, vector<int>& result) {
if (root == nullptr) {
return;
}
result.push_back(root->value); // Visit root
preorderTraversal(root->left, result); // Visit left subtree
preorderTraversal(root->right, result); // Visit right subtree
}

// Function to create a binary tree from input


Node* buildBinaryTree(const vector<string>& nodeValues) {
if (nodeValues.empty() || nodeValues[0] == "null") {
return nullptr;
}
Node* root = new Node(stoi(nodeValues[0]));
queue<Node*> nodeQueue;
nodeQueue.push(root);
int index = 1;
while (!nodeQueue.empty() && index < nodeValues.size()) {
Node* currentNode = nodeQueue.front();
nodeQueue.pop();
// Create left child
if (index < nodeValues.size() && nodeValues[index] != "null") {
currentNode->left = new Node(stoi(nodeValues[index]));
nodeQueue.push(currentNode->left);
}
index++;
8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
// Create right child
if (index < nodeValues.size() && nodeValues[index] != "null") {
currentNode->right = new Node(stoi(nodeValues[index]));
nodeQueue.push(currentNode->right);
}
index++;
}
return root;
}

int main() {
string input;
cout << "Enter the binary tree nodes in level order (use 'null' for empty nodes, space-separated): ";
getline(cin, input);
// Split the input string into a vector
stringstream ss(input);
vector<string> nodeValues;
string value;
while (ss >> value) {
nodeValues.push_back(value);
}
Node* root = buildBinaryTree(nodeValues); // Create the binary tree
vector<int> traversalResult; // Vector to store the preorder traversal result
preorderTraversal(root, traversalResult); // Perform preorder traversal
// Output the result
cout << "Preorder traversal: ";
for (int val : traversalResult) {
cout << val << " ";
}
cout << endl;
return 0;
}

OUTPUT:

EASY

1. Invert Binary Tree

Given the root of a binary tree, invert the tree, and return its root.

Example 1:

8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

Input: root = [4,2,7,1,3,6,9]


Output: [4,7,2,9,6,3,1]

Example 2:

Input: root = [2,1,3]


Output: [2,3,1]

Constraints:
The number of nodes in the tree is in the range [0, 100].
-100 <= Node.val <= 100

CODE:
#include <iostream>
#include <vector>
#include <queue>
#include <sstream>

using namespace std;

// Definition for a binary tree node.


struct Node {
int data;
Node *left;
Node *right;
Node(int value) : data(value), left(nullptr), right(nullptr) {}
};

// Function to invert the binary tree


Node* reverseBinaryTree(Node* root) {
if (root == nullptr) {
return nullptr; // Base case: if the tree is empty
}
// Swap the left and right children
swap(root->left, root->right);
// Recursively invert the left and right subtrees
reverseBinaryTree(root->left);
8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
reverseBinaryTree(root->right);
return root; // Return the root of the inverted tree
}

// Function to create a binary tree from input


Node* buildBinaryTree(const vector<string>& nodeValues) {
if (nodeValues.empty() || nodeValues[0] == "null") {
return nullptr;
}

Node* root = new Node(stoi(nodeValues[0]));


queue<Node*> nodeQueue;
nodeQueue.push(root);
int idx = 1;

while (!nodeQueue.empty() && idx < nodeValues.size()) {


Node* currentNode = nodeQueue.front();
nodeQueue.pop();

// Create left child


if (idx < nodeValues.size() && nodeValues[idx] != "null") {
currentNode->left = new Node(stoi(nodeValues[idx]));
nodeQueue.push(currentNode->left);
}
idx++;

// Create right child


if (idx < nodeValues.size() && nodeValues[idx] != "null") {
currentNode->right = new Node(stoi(nodeValues[idx]));
nodeQueue.push(currentNode->right);
}
idx++;
}

return root;
}

// Function to perform level order traversal and print the tree


void levelOrderPrint(Node* root) {
if (root == nullptr) {
cout << "[]";
return;
}

queue<Node*> nodeQueue;
nodeQueue.push(root);
8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
cout << "[";
while (!nodeQueue.empty()) {
Node* currentNode = nodeQueue.front();
nodeQueue.pop();
if (currentNode) {
cout << currentNode->data << ",";
nodeQueue.push(currentNode->left);
nodeQueue.push(currentNode->right);
} else {
cout << "null,";
}
}
cout << "\b]"; // Remove the last comma
}

int main() {
string input;
cout << "Enter the binary tree nodes in level order (use 'null' for empty nodes, space-separated): ";
getline(cin, input);

// Split the input string into a vector


stringstream ss(input);
vector<string> nodeValues;
string value;
while (ss >> value) {
nodeValues.push_back(value);
}

Node* root = buildBinaryTree(nodeValues); // Create the binary tree


root = reverseBinaryTree(root); // Invert the binary tree

// Output the inverted tree


cout << "Inverted binary tree: ";
levelOrderPrint(root);
cout << endl;

return 0;
}

OUTPUT:

8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

MEDIUM

1. Construct Binary Tree from Preorder and Inorder Traversal

Given two integer arrays preorder and inorder where preorder is the preorder traversal of a binary tree and
inorder is the inorder traversal of the same tree, construct and return the binary tree.

Example 1:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]

Example 2:
Input: preorder = [-1], inorder = [-1]
Output: [-1]

Constraints:
1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
preorder and inorder consist of unique values.
Each value of inorder also appears in preorder.
preorder is guaranteed to be the preorder traversal of the tree.
inorder is guaranteed to be the inorder traversal of the tree.

CODE:
#include <iostream>
#include <vector>
#include <queue> // Include the queue header
#include <unordered_map>
#include <sstream>
using namespace std;

// Definition for a binary tree node.


struct Node {
int data;
Node *left;
Node *right;
Node(int value) : data(value), left(nullptr), right(nullptr) {}
};

// Function to build the binary tree from preorder and inorder traversals
Node* constructTreeHelper(vector<int>& preorder, int preStart, int preEnd,
vector<int>& inorder, int inStart, int inEnd, unordered_map<int, int>& indexMap) {
if (preStart > preEnd || inStart > inEnd) {
8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
return nullptr; // Base case: no elements to construct the tree
}

// The first element in preorder is the root


int rootValue = preorder[preStart];
Node* root = new Node(rootValue);

// Find the index of the root in inorder


int rootIndex = indexMap[rootValue];

// Calculate the size of the left subtree


int leftSubtreeSize = rootIndex - inStart;

// Recursively build the left and right subtrees


root->left = constructTreeHelper(preorder, preStart + 1, preStart + leftSubtreeSize, inorder, inStart,
rootIndex - 1, indexMap);
root->right = constructTreeHelper(preorder, preStart + leftSubtreeSize + 1, preEnd, inorder, rootIndex +
1, inEnd, indexMap);
return root;
}

// Main function to build the binary tree


Node* buildBinaryTree(vector<int>& preorder, vector<int>& inorder) {
unordered_map<int, int> indexMap; // Map to store the index of each value in inorder
for (int i = 0; i < inorder.size(); ++i) {
indexMap[inorder[i]] = i;
}
return constructTreeHelper(preorder, 0, preorder.size() - 1, inorder, 0, inorder.size() - 1, indexMap);
}

// Function to perform level order traversal and print the tree


void levelOrderTraversal(Node* root) {
if (root == nullptr) {
cout << "[]";
return;
}

queue<Node*> nodeQueue; // Declare the queue


nodeQueue.push(root);
cout << "[";

while (!nodeQueue.empty()) {
Node* currentNode = nodeQueue.front();
nodeQueue.pop();
if (currentNode) {
cout << currentNode->data << ",";
8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
nodeQueue.push(currentNode->left);
nodeQueue.push(currentNode->right);
} else {
cout << "null,";
}
}
cout << "\b]"; // Remove the last comma
}

int main() {
int numNodes;
cout << "Enter the number of nodes: ";
cin >> numNodes;

vector<int> preorder(numNodes);
vector<int> inorder(numNodes);

cout << "Enter the preorder traversal (space-separated): ";


for (int i = 0; i < numNodes; ++i) {
cin >> preorder[i];
}

cout << "Enter the inorder traversal (space-separated): ";


for (int i = 0; i < numNodes; ++i) {
cin >> inorder[i];
}

Node* root = buildBinaryTree(preorder, inorder); // Build the binary tree

// Output the constructed binary tree


cout << "Constructed binary tree (level order): ";
levelOrderTraversal(root);
cout << endl;

return 0;
}

OUTPUT:

8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
2. Lowest Common Ancestor of a Binary Tree

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.

The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p
and q as descendants (where we allow a node to be a descendant of itself).

Example 1:

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1


Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.

Example 2:

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4


Output: 5
Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to
the LCA definition.

Example 3:
Input: root = [1,2], p = 1, q = 2
Output: 1

Constraints:
The number of nodes in the tree is in the range [2, 105].
-109 <= Node.val <= 109
All Node.val are unique.
p != q
p and q will exist in the tree.

CODE:
8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
#include <iostream>
#include <vector>
#include <queue>
#include <sstream>
#include <unordered_map>

using namespace std;

// Definition for a binary tree node.


struct Node {
int value;
Node *left;
Node *right;
Node(int x) : value(x), left(nullptr), right(nullptr) {}
};

// Function to build the binary tree from input


Node* createTree(const vector<string>& elements) {
if (elements.empty() || elements[0] == "null") {
return nullptr;
}

Node* root = new Node(stoi(elements[0]));


queue<Node*> nodeQueue;
nodeQueue.push(root);
int index = 1;
while (!nodeQueue.empty() && index < elements.size()) {
Node* currentNode = nodeQueue.front();
nodeQueue.pop();
// Create left child
if (index < elements.size() && elements[index] != "null") {
currentNode->left = new Node(stoi(elements[index]));
nodeQueue.push(currentNode->left);
}
index++;
// Create right child
if (index < elements.size() && elements[index] != "null") {
currentNode->right = new Node(stoi(elements[index]));
nodeQueue.push(currentNode->right);
}
index++;
}

return root;
}

8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
// Function to find the lowest common ancestor of two nodes
Node* findLCA(Node* root, Node* p, Node* q) {
if (root == nullptr || root == p || root == q) {
return root; // Base case: if root is null or matches p or q
}

Node* left = findLCA(root->left, p, q); // Search in left subtree


Node* right = findLCA(root->right, p, q); // Search in right subtree

if (left && right) {


return root; // If both left and right are non-null, root is LCA
}
return left ? left : right; // Return the non-null child
}

// Function to find a node in the tree by value


Node* searchNode(Node* root, int value) {
if (root == nullptr) return nullptr;
if (root->value == value) return root;
Node* left = searchNode(root->left, value);
return left ? left : searchNode(root->right, value);
}

int main() {
string input;
cout << "Enter the binary tree nodes in level order (use 'null' for empty nodes, space-separated): ";
getline(cin, input);
// Split the input string into a vector
stringstream ss(input);
vector<string> elements;
string element;
while (ss >> element) {
elements.push_back(element);
}
Node* root = createTree(elements); // Create the binary tree

int value1, value2;


cout << "Enter the values of nodes p and q: ";
cin >> value1 >> value2;

Node* p = searchNode(root, value1);


Node* q = searchNode(root, value2);

if (p && q) {
Node* lca = findLCA(root, p, q); // Find the LCA
cout << "The LCA of nodes " << value1 << " and " << value2 << " is: " << lca->value << endl;
8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
} else {
cout << "One or both of the nodes do not exist in the tree." << endl;
}

return 0;
}

OUTPUT:

3. Sum Root to Leaf Numbers

You are given the root of a binary tree containing digits from 0 to 9 only.

Each root-to-leaf path in the tree represents a number.

For example, the root-to-leaf path 1 -> 2 -> 3 represents the number 123.
Return the total sum of all root-to-leaf numbers. Test cases are generated so that the answer will fit in a 32-
bit integer.

A leaf node is a node with no children.

Example 1:

Input: root = [1,2,3]Output: 25


Explanation:
The root-to-leaf path 1->2 represents the number 12.
The root-to-leaf path 1->3 represents the number 13.
Therefore, sum = 12 + 13 = 25.
Example 2:

Input: root = [4,9,0,5,1]Output: 1026


8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
Explanation:
The root-to-leaf path 4->9->5 represents the number 495.
The root-to-leaf path 4->9->1 represents the number 491.
The root-to-leaf path 4->0 represents the number 40.
Therefore, sum = 495 + 491 + 40 = 1026.

Constraints:
The number of nodes in the tree is in the range [1, 1000].
0 <= Node.val <= 9
The depth of the tree will not exceed 10.

CODE:
#include <iostream>
#include <vector>
#include <queue>
#include <sstream>

using namespace std;

// Definition for a binary tree node.


struct Node {
int value;
Node *left;
Node *right;
Node(int x) : value(x), left(nullptr), right(nullptr) {}
};

// Function to build the binary tree from input


Node* buildTree(const vector<string>& elements) {
if (elements.empty() || elements[0] == "null") {
return nullptr;
}

Node* root = new Node(stoi(elements[0]));


queue<Node*> nodeQueue;
nodeQueue.push(root);
int idx = 1;

while (!nodeQueue.empty() && idx < elements.size()) {


Node* currentNode = nodeQueue.front();
nodeQueue.pop();

// Create left child


if (idx < elements.size() && elements[idx] != "null") {
currentNode->left = new Node(stoi(elements[idx]));
nodeQueue.push(currentNode->left);
8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
}
idx++;

// Create right child


if (idx < elements.size() && elements[idx] != "null") {
currentNode->right = new Node(stoi(elements[idx]));
nodeQueue.push(currentNode->right);
}
idx++;
}

return root;
}

// Function to calculate the sum of all root-to-leaf numbers


void computeRootToLeafSum(Node* root, int currentSum, int& totalSum) {
if (root == nullptr) {
return; // Base case: if the node is null
}

// Update the current sum


currentSum = currentSum * 10 + root->value;

// If it's a leaf node, add the current sum to the total sum
if (root->left == nullptr && root->right == nullptr) {
totalSum += currentSum;
} else {
// Recur for left and right children
computeRootToLeafSum(root->left, currentSum, totalSum);
computeRootToLeafSum(root->right, currentSum, totalSum);
}
}

// Main function to calculate the sum of all root-to-leaf numbers


int sumOfRootToLeafNumbers(Node* root) {
int totalSum = 0;
computeRootToLeafSum(root, 0, totalSum);
return totalSum;
}

int main() {
string input;
cout << "Enter the binary tree nodes in level order (use 'null' for empty nodes, space-separated): ";
getline(cin, input);

// Split the input string into a vector


8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
stringstream ss(input);
vector<string> elements;
string element;
while (ss >> element) {
elements.push_back(element);
}

Node* root = buildTree(elements); // Create the binary tree

// Calculate the sum of all root-to-leaf numbers


int totalSum = sumOfRootToLeafNumbers(root);
cout << "The total sum of all root-to-leaf numbers is: " << totalSum << endl;

return 0;
}

OUTPUT:

HARD
1. Populating Next Right Pointers in Each Node

Given a binary tree


struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
Populate each next pointer to point to its next right node. If there is no next right node, the next pointer
should be set to NULL.

Initially, all next pointers are set to NULL.

Example 1:

8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

Input: root = [1,2,3,4,5,null,7]


Output: [1,#,2,3,#,4,5,7,#]
Explanation: Given the above binary tree (Figure A), your function should populate each next pointer
to point to its next right node, just like in Figure B. The serialized output is in level order as connected
by the next pointers, with '#' signifying the end of each level.

Example 2:
Input: root = []Output: []

Constraints:
The number of nodes in the tree is in the range [0, 6000].
-100 <= Node.val <= 100

Follow-up:
You may only use constant extra space.
The recursive approach is fine. You may assume implicit stack space does not count as extra space for
this problem.

CODE:
#include <iostream>
#include <vector>
#include <queue>
#include <sstream>

using namespace std;

// Definition for a binary tree node.


struct TreeNode {
int data;
TreeNode *left;
TreeNode *right;
TreeNode *next;
TreeNode(int value) : data(value), left(nullptr), right(nullptr), next(nullptr) {}
};

// Function to build the binary tree from input


TreeNode* buildTree(const vector<string>& elements) {
if (elements.empty() || elements[0] == "null") {
8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
return nullptr;
}

TreeNode* root = new TreeNode(stoi(elements[0]));


queue<TreeNode*> nodeQueue;
nodeQueue.push(root);
int idx = 1;

while (!nodeQueue.empty() && idx < elements.size()) {


TreeNode* currentNode = nodeQueue.front();
nodeQueue.pop();

// Create left child


if (idx < elements.size() && elements[idx] != "null") {
currentNode->left = new TreeNode(stoi(elements[idx]));
nodeQueue.push(currentNode->left);
}
idx++;

// Create right child


if (idx < elements.size() && elements[idx] != "null") {
currentNode->right = new TreeNode(stoi(elements[idx]));
nodeQueue.push(currentNode->right);
}
idx++;
}

return root;
}

// Function to connect next right pointers


void connectNextPointers(TreeNode* root) {
if (root == nullptr) return;

queue<TreeNode*> nodeQueue;
nodeQueue.push(root);

while (!nodeQueue.empty()) {
int levelSize = nodeQueue.size();
TreeNode* previous = nullptr;

for (int i = 0; i < levelSize; ++i) {


TreeNode* currentNode = nodeQueue.front();
nodeQueue.pop();

if (previous != nullptr) {
8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
previous->next = currentNode; // Connect the previous node's next to the current node
}
previous = currentNode; // Update previous to the current node

// Push left and right children to the queue


if (currentNode->left) nodeQueue.push(currentNode->left);
if (currentNode->right) nodeQueue.push(currentNode->right);
}
// The last node in the level points to NULL
if (previous != nullptr) {
previous->next = nullptr;
}
}
}

// Function to print the tree level order with next pointers


void printTreeWithNextPointers(TreeNode* root) {
if (root == nullptr) {
cout << "[]";
return;
}

queue<TreeNode*> nodeQueue;
nodeQueue.push(root);
cout << "[";
while (!nodeQueue.empty()) {
TreeNode* currentNode = nodeQueue.front();
nodeQueue.pop();
if (currentNode) {
cout << currentNode->data;
if (currentNode->next) {
cout << " -> " << currentNode->next->data;
} else {
cout << " -> #"; // Indicate the end of the level
}
cout << ", ";
if (currentNode->left) nodeQueue.push(currentNode->left);
if (currentNode->right) nodeQueue.push(currentNode->right);
}
}
cout << "\b\b]"; // Remove the last comma and space
}

int main() {
string input;
cout << "Enter the binary tree nodes in level order (use 'null' for empty nodes, space-separated): ";
8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
getline(cin, input);

// Split the input string into a vector


stringstream ss(input);
vector<string> elements;
string element;
while (ss >> element) {
elements.push_back(element);
}

TreeNode* root = buildTree(elements); // Create the binary tree

// Populate next right pointers


connectNextPointers(root);

// Output the tree with next pointers


cout << "The tree with next pointers populated: ";
printTreeWithNextPointers(root);
cout << endl;

return 0;
}

OUTPUT:

VERY HARD

1. Count Paths That Can Form a Palindrome in a Tree

You are given a tree (i.e. a connected, undirected graph that has no cycles) rooted at node 0 consisting
of n nodes numbered from 0 to n - 1. The tree is represented by a 0-indexed array parent of size n,
where parent[i] is the parent of node i. Since node 0 is the root, parent[0] == -1.
You are also given a string s of length n, where s[i] is the character assigned to the edge
between i and parent[i]. s[0] can be ignored.
Return the number of pairs of nodes (u, v) such that u < v and the characters assigned to edges on the path
from u to v can be rearranged to form a palindrome.
A string is a palindrome when it reads the same backwards as forwards.

Example 1:

8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

Input: parent = [-1,0,0,1,1,2], s = "acaabc"


Output: 8
Explanation: The valid pairs are:
- All the pairs (0,1), (0,2), (1,3), (1,4) and (2,5) result in one character which is always a palindrome.
- The pair (2,3) result in the string "aca" which is a palindrome.
- The pair (1,5) result in the string "cac" which is a palindrome.
- The pair (3,5) result in the string "acac" which can be rearranged into the palindrome "acca".

Example 2:
Input: parent = [-1,0,0,0,0], s = "aaaaa"
Output: 10
Explanation: Any pair of nodes (u,v) where u < v is valid.

Constraints:
n == parent.length == s.length
1 <= n <= 105
0 <= parent[i] <= n - 1 for all i >= 1
parent[0] == -1
parent represents a valid tree.
s consists of only lowercase English letters.

CODE:
#include <iostream>
#include <vector>
#include <unordered_map>
#include <string>

using namespace std;

class PairCounter {
public:
int calculatePairs(vector<int>& parentArray, string& characters) {
int length = parentArray.size();
vector<vector<int>> treeStructure(length);

// Build the tree from the parent array


8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING
for (int i = 1; i < length; ++i) {
treeStructure[parentArray[i]].push_back(i);
}

// To store the count of valid pairs


int pairCount = 0;

// Map to store the frequency of character bitmasks


unordered_map<int, int> bitmaskFrequency;
bitmaskFrequency[0] = 1; // Base case: empty path

// DFS to count pairs


depthFirstSearch(0, 0, treeStructure, characters, bitmaskFrequency, pairCount);

return pairCount;
}

private:
void depthFirstSearch(int node, int bitmask, vector<vector<int>>& tree, string& chars,
unordered_map<int, int>& bitmaskFrequency, int& pairCount) {
// Update the bitmask for the current character
bitmask ^= (1 << (chars[node] - 'a'));

// Count the number of valid pairs with the current bitmask


pairCount += bitmaskFrequency[bitmask]; // Count pairs with the same bitmask
for (int i = 0; i < 26; ++i) {
pairCount += bitmaskFrequency[bitmask ^ (1 << i)]; // Count pairs with one character different
}

// Increment the frequency of the current bitmask


bitmaskFrequency[bitmask]++;

// Recur for all children


for (int child : tree[node]) {
depthFirstSearch(child, bitmask, tree, chars, bitmaskFrequency, pairCount);
}

// Decrement the frequency of the current bitmask after returning from DFS
bitmaskFrequency[bitmask]--;
}
};

int main() {
int nodeCount;
cout << "Enter the number of nodes: ";
cin >> nodeCount;
8
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

vector<int> parentArray(nodeCount);
cout << "Enter the parent array: ";
for (int i = 0; i < nodeCount; ++i) {
cin >> parentArray[i];
}

string characters;
cout << "Enter the string s: ";
cin >> characters;

PairCounter solution;
int result = solution.calculatePairs(parentArray, characters);
cout << "The number of valid pairs is: " << result << endl;

return 0;
}

OUTPUT:

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy