Coding Interview Question: Find Width of a Tree

This is the second article in the series about tree-related coding interview questions. In the previous article, we took a look at how to traverse a binary and a non-binary tree in a breadth-first manner. However, only traversing a tree is not very useful. In an interview setting, you would most likely be asked to go through a tree and do some kind of manipulation on the nodes or get some information about them. A potential interview question could be related to finding the width of the tree.

The Problem

Given the root of a tree, return an array with the length of each level.

Example of a non-binary tree

Given this tree, we would have to return an array [1, 3, 3, 2].

Before we even start solving the problem, we need to figure out whether to use breadth-first or depth-first traversal. The answer should be clear just by looking at the tree: since we need to calculate the width of the tree, we should traverse it in a breadth-first manner. If we were asked for the length of it, we would reach out for the depth-first method.

The solution

Now we can get down to business! We’re given a root node, with information about its data and an array of its children. We need to go through the whole tree and make sure that we note down when the level changes.

We will reuse the traversal function that we have previously discussed in the Breadth-First Tree Traversal, Explained Simply (For Binary and Non-Binary Trees) article.

const traverseTree = () => {
  const toBeTraversedArray = [root];
  const traversedTree = []; 
  while (toBeTraversedArray.length > 0) {
let currentNode = toBeTraversedArray.shift();
traversedTree.push(currentNode);
  if (currentNode.children.length > 0) {
toBeTraversedArray.push(...currentNode.children);
}
 }  
return traversedTree;
}

With this function, we have more than half of the work done, as we are already traversing the whole tree and printing its nodes out in order of importance. However, it doesn’t quite solve the problem at hand, as we don’t know where one level ends and the other begins. To solve it, we need to do some modifications to our traverseTree function.

First, we need to make sure that every time we push children to the toBeTraversedArray, we “remember” that we have moved down by one level. One way to do it is by inserting some kind of a separator after we have pushed all the children of the current node to the toBeTraversedArray. This separator can be anything, as long as it’s not a node. I will be using a string x.

Before we do anything else, we check if the root element is passed to the function. If not, we just return an array with 0.

If the root element exists, we initiate the toBeTraversedArray with the root element and an x, indicating that there is only one element in the first loop.

We also need to keep count of the number of elements we have already traversed. And since we want to return all the counters in an array, we need an array for the counters as well.

I prefer to have a counter variable, which I increment on every loop and then push to the counterArray.

function getTreeWidth(root) {
const toBeTraversedArray = [root, 'x'];
let currentCounter = 0;
const counterArray = [];
}

We have to make sure that we push the separator to the end of the toBeTraversedArray because this will be the condition of our while loop. If there is only one element left in the array, it means it’s the separator and we have to escape the loop.

function getTreeWidth(root) {
if (!root) return [0];
  const toBeTraversedArray = [root, 'x'];
let currentCounter = 0;
const counterArray = [];
  while (toBeTraversedArray.length > 1) {
    const currentNode = toBeTraversedArray.shift();
    if (currentNode === 'x') {
counterArray.push(currentCounter);
currentCounter = 0;
toBeTraversedArray.push('x');
} else {
currentCounter++;
toBeTraversedArray.push(...currentNode.children);
}
}
}

In the loop itself, we get the first element of the toBeTraversedArrayand check if it’s the separator. If so, it means that we have reached the end of a level. We push our currentCounter to the counterArray, reset the currentCounter and push the separator back to the toBeTraversedArray.

If the element at hand is a node, we just add its children to the toBeTraversedArray so we can come back to them later and then we increment the currentCounter.

When traversal is done, we have to make sure to push the last counter to the counterArray before we return it.

And that’s it. Let’s check if our function works as expected.

class Node {
constructor(data) {
this.data = data;
this.children = [];
}
}
const  root = new Node('CEO');
const CTO = new Node('CTO');
const CMO = new Node('CMO');
const COO = new Node('COO');
const SeniorPM = new Node('Senior PM');
SeniorPM.children = [new Node('PM'), new Node('PM')];
CTO.children = [new Node('Director of Infra'), new Node('Director of Eng')]
CMO.children = [SeniorPM];
root.children = [CTO, CMO, COO];
console.log(traverseTree(root));

We get:

console.log result

This solution is not the only correct answer to this question, it’s just the one that makes the most sense to me.

If you have suggestions for improvement or would like to share another solution, feel free to leave a comment. Let’s learn from each other. 🙂

Follow me so you don’t miss the upcoming coding challenges, explained simply!

Build composable applications

Don’t build web monoliths. Use Bit to create and compose decoupled software components — in your favorite frameworks like React or Node. Build scalable and modular applications with a powerful and enjoyable dev experience.

Bring your team to Bit Cloud to host and collaborate on components together, and greatly speed up, scale, and standardize development as a team. Start with composable frontends like a Design System or Micro Frontends, or explore the composable backend. Give it a try →

Learn More


Coding Interview Question: Find Width of a Tree was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Bits and Pieces - Medium and was authored by Lina Suodyte

This is the second article in the series about tree-related coding interview questions. In the previous article, we took a look at how to traverse a binary and a non-binary tree in a breadth-first manner. However, only traversing a tree is not very useful. In an interview setting, you would most likely be asked to go through a tree and do some kind of manipulation on the nodes or get some information about them. A potential interview question could be related to finding the width of the tree.

The Problem

Given the root of a tree, return an array with the length of each level.

Example of a non-binary tree

Given this tree, we would have to return an array [1, 3, 3, 2].

Before we even start solving the problem, we need to figure out whether to use breadth-first or depth-first traversal. The answer should be clear just by looking at the tree: since we need to calculate the width of the tree, we should traverse it in a breadth-first manner. If we were asked for the length of it, we would reach out for the depth-first method.

The solution

Now we can get down to business! We’re given a root node, with information about its data and an array of its children. We need to go through the whole tree and make sure that we note down when the level changes.

We will reuse the traversal function that we have previously discussed in the Breadth-First Tree Traversal, Explained Simply (For Binary and Non-Binary Trees) article.

const traverseTree = () => {
  const toBeTraversedArray = [root];
  const traversedTree = []; 
  while (toBeTraversedArray.length > 0) {
let currentNode = toBeTraversedArray.shift();
traversedTree.push(currentNode);
  if (currentNode.children.length > 0) {
toBeTraversedArray.push(...currentNode.children);
}
 }  
return traversedTree;
}

With this function, we have more than half of the work done, as we are already traversing the whole tree and printing its nodes out in order of importance. However, it doesn’t quite solve the problem at hand, as we don’t know where one level ends and the other begins. To solve it, we need to do some modifications to our traverseTree function.

First, we need to make sure that every time we push children to the toBeTraversedArray, we “remember” that we have moved down by one level. One way to do it is by inserting some kind of a separator after we have pushed all the children of the current node to the toBeTraversedArray. This separator can be anything, as long as it’s not a node. I will be using a string x.

Before we do anything else, we check if the root element is passed to the function. If not, we just return an array with 0.

If the root element exists, we initiate the toBeTraversedArray with the root element and an x, indicating that there is only one element in the first loop.

We also need to keep count of the number of elements we have already traversed. And since we want to return all the counters in an array, we need an array for the counters as well.

I prefer to have a counter variable, which I increment on every loop and then push to the counterArray.

function getTreeWidth(root) {
const toBeTraversedArray = [root, 'x'];
let currentCounter = 0;
const counterArray = [];
}

We have to make sure that we push the separator to the end of the toBeTraversedArray because this will be the condition of our while loop. If there is only one element left in the array, it means it’s the separator and we have to escape the loop.

function getTreeWidth(root) {
if (!root) return [0];
  const toBeTraversedArray = [root, 'x'];
let currentCounter = 0;
const counterArray = [];
  while (toBeTraversedArray.length > 1) {
    const currentNode = toBeTraversedArray.shift();
    if (currentNode === 'x') {
counterArray.push(currentCounter);
currentCounter = 0;
toBeTraversedArray.push('x');
} else {
currentCounter++;
toBeTraversedArray.push(...currentNode.children);
}
}
}

In the loop itself, we get the first element of the toBeTraversedArrayand check if it’s the separator. If so, it means that we have reached the end of a level. We push our currentCounter to the counterArray, reset the currentCounter and push the separator back to the toBeTraversedArray.

If the element at hand is a node, we just add its children to the toBeTraversedArray so we can come back to them later and then we increment the currentCounter.

When traversal is done, we have to make sure to push the last counter to the counterArray before we return it.

And that’s it. Let’s check if our function works as expected.

class Node {
constructor(data) {
this.data = data;
this.children = [];
}
}
const  root = new Node('CEO');
const CTO = new Node('CTO');
const CMO = new Node('CMO');
const COO = new Node('COO');
const SeniorPM = new Node('Senior PM');
SeniorPM.children = [new Node('PM'), new Node('PM')];
CTO.children = [new Node('Director of Infra'), new Node('Director of Eng')]
CMO.children = [SeniorPM];
root.children = [CTO, CMO, COO];
console.log(traverseTree(root));

We get:

console.log result

This solution is not the only correct answer to this question, it’s just the one that makes the most sense to me.

If you have suggestions for improvement or would like to share another solution, feel free to leave a comment. Let’s learn from each other. 🙂

Follow me so you don’t miss the upcoming coding challenges, explained simply!

Build composable applications

Don’t build web monoliths. Use Bit to create and compose decoupled software components — in your favorite frameworks like React or Node. Build scalable and modular applications with a powerful and enjoyable dev experience.

Bring your team to Bit Cloud to host and collaborate on components together, and greatly speed up, scale, and standardize development as a team. Start with composable frontends like a Design System or Micro Frontends, or explore the composable backend. Give it a try →

Learn More


Coding Interview Question: Find Width of a Tree was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Bits and Pieces - Medium and was authored by Lina Suodyte


Print Share Comment Cite Upload Translate Updates
APA

Lina Suodyte | Sciencx (2022-03-23T09:44:59+00:00) Coding Interview Question: Find Width of a Tree. Retrieved from https://www.scien.cx/2022/03/23/coding-interview-question-find-width-of-a-tree/

MLA
" » Coding Interview Question: Find Width of a Tree." Lina Suodyte | Sciencx - Wednesday March 23, 2022, https://www.scien.cx/2022/03/23/coding-interview-question-find-width-of-a-tree/
HARVARD
Lina Suodyte | Sciencx Wednesday March 23, 2022 » Coding Interview Question: Find Width of a Tree., viewed ,<https://www.scien.cx/2022/03/23/coding-interview-question-find-width-of-a-tree/>
VANCOUVER
Lina Suodyte | Sciencx - » Coding Interview Question: Find Width of a Tree. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/03/23/coding-interview-question-find-width-of-a-tree/
CHICAGO
" » Coding Interview Question: Find Width of a Tree." Lina Suodyte | Sciencx - Accessed . https://www.scien.cx/2022/03/23/coding-interview-question-find-width-of-a-tree/
IEEE
" » Coding Interview Question: Find Width of a Tree." Lina Suodyte | Sciencx [Online]. Available: https://www.scien.cx/2022/03/23/coding-interview-question-find-width-of-a-tree/. [Accessed: ]
rf:citation
» Coding Interview Question: Find Width of a Tree | Lina Suodyte | Sciencx | https://www.scien.cx/2022/03/23/coding-interview-question-find-width-of-a-tree/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.