A Google Interview Question
Tags: challenge, codenewbie, javascript, career
Published: 2020-10-22 13:46:48

Welcome back to Code Review. If you're just joining us, learn more about [Coderbyte's](https://coderbyte.com/) weekly coding challenges and solve our first challenge [here](https://dev.to/coderbyte/reintroducing-code-review-with-an-interview-question-asked-at-amazon-5a89).

I hope everyone had a great week (and have made plans to vote).  Let's jump right into the solution from [last week's challenge](https://dev.to/cindyytong/a-facebook-interview-question-14b1) which featured a Facebook interview question.

## Last Week's Challenge
For the `treeConstructor` challenge we were asked to write a function which takes in an array containing strings that each have pairs of integers in the following format: `(i1,i2)`, where `i1` represents a child node in a tree and the second integer `i2` signifies that it is the parent of `i1`. Our goal is to return `true` if the values can form a binary tree, and return `false` if not.  If you'd like to see how your solution compares with over 500,000 other users, visit the challenge page at Coderbyte [here](https://coderbyte.com/information/Find%20Intersection). 

## Last Week's Solution
Before coding let's do a quick review of what a binary tree is. If you need a more thorough review, check out our video series on trees [here](https://www.youtube.com/watch?v=dfaKCrJ2HAk&list=PLxQ8cCJ6LyOZcCW4omAoUzUFFhQ2ud3tD&index=1).  To understand what a binary tree is, we must first define what a tree is. A tree is a collection of nodes where:
  
**Condition 1** There is one root node (or one parent node).

**Condition 2** There is only a single path between any two nodes (every child node has one parent node).

A Binary Tree is a special type of tree where:

**Condition 3** Each node in the tree has at most two children. This means that a node can have none, one or two children. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/01gi7ikj8buzqs8020b6.jpg)
*Screenshot from our youtube [video series](https://www.youtube.com/watch?v=dfaKCrJ2HAk&list=PLxQ8cCJ6LyOZcCW4omAoUzUFFhQ2ud3tD&index=1) on Trees*

Now that we know what a binary tree is, let's pseudocode an approach to how we would solve this problem.

1. Because we will need a way to separate children from parents so we can check the above conditions, we can create hash tables where we store the parent:child and child:parent relationships.
- For parents, we'll construct: something like the following ` parents = { p1: [c1, ch2], p2: [c3]}`,
- For children we'll have `children = { c1: p1, c2: p2 }`

2. Then we'll need to iterate across the array of strings and for each string combo: 

* Parse the string `"(child, parent)"` so that we can easily work with the `child` and `parent` by using semantic variables.
* Check if the current parent already exists in the parents hash. If it does, add the child to the array. If not, create a new array with the child in it. If the length of the array children for the current parent is longer than 2, then we violate condition 3 and should return false. 
* If the current child already exists in the children hash, return false since we violate condition 2 (the child has more than one parent). Otherwise, add the child and corresponding parent to the children hash. 
* Check condition 1 holds true by ensuring that there is only one root node (one node without a parent). 

```javascript
function treeConstructor(strArr) {
    let parents = {};
    let children = {};

    for (let i = 0; i < strArr.length; i++) {
        // i.e. ("1,2") => ["1", "2"]
        let pair = strArr[i].replace(/[()]/g, "").split(",");
        let child = pair[0];
        let parent = pair[1];

        //  check parents have at most 2 children 
        if (parents[parent]) {
            parents[parent].push(child);
        } else {
            parents[parent] = [child];
        }

        if (parents[parent].length > 2) {
            return false;
        }

        // check child has one parent 
        if (children[child]) {
            return false;
        } else {
            children[child] = parent;
        }
    }
    // check there is only one root node 
        let root_count = 0;
        let parent_values = Object.keys(parents)
        for(let i = 0; i < parent_values.length; i++){
            if(!children[parent_values[i]]){
                root_count += 1;
            }
            if(root_count > 1){
                return false;
            }
        }
    return true;
}

// Given test cases 
console.log(treeConstructor(["(1,2)", "(2,4)", "(5,7)", "(7,2)", "(9,5)"])) // return true 

console.log(treeConstructor(["(1,2)", "(1,3)"])) // return false since we have a child with more than 1 parent

// Additional test cases 
console.log(treeConstructor(["(1,2)", "(3,2)", "(4,2)"])) // return false since we have a parent with more than 2 children 
console.log(treeConstructor(["(3,2)", "(4,5)" ])) // return false where we have disconnected nodes (more than 1 parent)
```

That's my approach to solving Tree Constructor. If I were solving this problem in a live interview, what I like about my appraoch is that I started first with the conditions that needed to hold true for us to construct a valid binary tree and then solved for these scenarios one at a time without trying to solve for everything at once. This made the problem much more approachable for me. Nevertheless, there are ways we can optimize this solution. What do you think we could improve? 

## This week's challenge 
We have a challenge used during a Google interview that requires us to work with matrices (something I was horried of when I first started solving algorithmic questions).

For this week's challenge, we are asked to write a function `bitmapHoles` that takes in `strArr` which is an array of strings that form a 2D matrix of 0 and 1's.  The function should determine how many holes, or contiguous regions of 0's, exist in the matrix. A contiguous region is one where there is a connected group of 0's going in one or more of four directions: up, down, left, or right. 

**Example 1**
If strArr is `["10111", "10101", "11101", "11111"]`, then this looks like the following matrix:
```javascript 
1 0 1 1 1
1 0 1 0 1
1 1 1 0 1
1 1 1 1 1
```

For the input above, your function should **return 2** because there are two separate contiguous regions of 0's, which create "holes" in the matrix. 

**Additional Examples**
* For `strArr = ["01111", "01101", "00011", "11110"]`, return 2.
* For `strArr = ["1011", "0010"]`, return 2.
* For `strArr = ["110", "000", "111"]`, return 2.  

You can assume that input `strArr` will not be empty.

## How will you solve this challenge?
I'd love to see how you would approach solving this problem. If you have any tips on future challenges you'd like us to cover during Code Review, feel free to comment below. If you're looking for more interview prep tips and learning tools, check out [Coderbyte](https://coderbyte.com/). See you next week! 


*<span>Photo by <a href="https://unsplash.com/@jplenio?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Johannes Plenio</a> on <a href="https://unsplash.com/s/photos/trees?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span>*