Facebook Interview Question for SDE1s


Country: United States




Comment hidden because of low score. Click to expand.
0
of 0 vote

So if there are 5 islands in the grid, then we are supposed to return perimeter of all 5 islands?

- Panda November 07, 2017 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I assume that islands are solid. I.e. an island can't have a lake in the middle.
The idea is to walk along the shore.

#include<iostream>
#include<vector>
#include<stack>

using namespace std;

bool Shore(vector<vector<int>> const &m, int r, int c)
{
	if (r >= 0 &&
		r < m.size() &&
		c >= 0 &&
		c < m[r].size() &&
		m[r][c] == 1)
	{
		if (r + 1 >= m.size() ||
			r - 1 < 0 ||
			c + 1 >= m[r].size() ||
			c - 1 < 0 ||
			m[r + 1][c] == 0 ||
			m[r - 1][c] == 0 ||
			m[r][c + 1] == 0 ||
			m[r][c - 1] == 0)
		{
			return true;
		}
	}
	return false;
}

int PerimeterFromCell(vector<vector<int>> &m, int r, int c)
{
	int perimeter = 0;
	stack<pair<int, int>> st;
	st.push(pair<int, int>(r, c));
	while (!st.empty()) {
		r = st.top().first;
		c = st.top().second;
		st.pop();
		if (Shore(m, r, c)) {
			++perimeter;
			st.push(pair<int, int>(r + 1, c));
			st.push(pair<int, int>(r - 1, c));
			st.push(pair<int, int>(r, c + 1));
			st.push(pair<int, int>(r, c - 1));
			m[r][c] = 2;
		}
	}
	return perimeter;
}

vector<int> Perimeters(vector<vector<int>> &m)
{
	vector<int> out;
	for (int r = 0; r < m.size(); ++r) {
		for (int c = 0; c < m[r].size(); ++c) {
			int perimeter = PerimeterFromCell(m, r, c);
			if (perimeter > 0) {
				out.push_back(perimeter);
			}
		}
	}
	return out;
}

int main()
{
	vector<vector<int>> m = {
		{0,0,0,0,1,1,1,1},
		{0,1,1,1,0,0,1,1},
		{0,1,1,1,0,0,1,1},
		{0,1,1,0,0,1,0,0},
		{0,0,0,1,1,1,0,0},
		{0,0,0,1,1,1,1,0},
		{0,1,0,1,1,1,1,0}
	};

	vector<int> out = Perimeters(m);
	for (int n : out) {
		cout << n << ", ";
	}
	cout << "\n";
	return 0;
}

- Alex November 08, 2017 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

If perimeter is the number of steps to walk around an island, you can just search for connected components and count, how many of those are pieces that border to the water.

This will detect islands and islands within islands and the perimiter for the case of islands with a lake just include the inner shore line.

An alternative, is to use a maze runner, it's more complicated tough. This way, it detects only the outer shore line and ignores the inner part of the island. That way it can get fast on large islands, but it will not detect islands within islands.

/*
000
010
000
perimeter = 1

0000
0110
0110
0000
perimeter = 4

00000
01110
01010
01010
01110
00000
perimter = 10

0000000
0*****0
00**1*0
000***0
0000000
* indicates perimeter (would be '1's)
perimeter = 11

0000000
0*****0
0000000
perimeter = 5 

0000000
0*000*0
0*****0
0**0*00
perimeter = 10
*/

#include <vector>
#include <queue>
#include <array>
#include <iostream>

using namespace std;

const int DIRECTIONS = 4; // up,right,down,left
const array<array<int, 2>, DIRECTIONS> MOVES{ { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 } } };
const array<array<int, 2>, DIRECTIONS> LEFT_FIELD{ {{0, -1}, { -1, 0 }, {0, 1}, { 1, 0 } } };

ostream& operator <<(ostream& os, const vector<int>& v);
ostream& operator <<(ostream& os, const vector<vector<int>>& vv);

bool is_within_map(vector<vector<int>>& map, int x, int y);
bool is_unvisited_land(vector<vector<int>>& map, int x, int y);
bool is_water(vector<vector<int>>& map, int x, int y);
bool is_unvisited_water(vector<vector<int>>& map, int x, int y);
bool is_waterLeft(vector<vector<int>>& map, int x, int y, int d);

vector<int> calc_perimeter(vector<vector<int>>& map)
{
	vector<int> result;
	deque<pair<int, int>> s;
	for (int x = 0; x < map.size(); ++x) s.push_front({ x, -1 });
	while (!s.empty()) {
		int x = s.back().first;
		int y = s.back().second;
		s.pop_back();
		if (is_unvisited_land(map, x, y)) {
			// start maze runner here
			int perimeter = 0;
			int d = 0, ox = -1, oy = -1, od = 0; // originates from
			do {
				if (is_unvisited_land(map, x, y)) { // if it hasn't been visited
					map[x][y] = 3; // visited land
					perimeter++; // count the field as perimeter
				}
				if (is_unvisited_water(map, x, y + 1)) { // keep scanning
					s.push_front({ x, y + 1 });
				}
				// adjust direction to not walk into water
				for (int i = 0; i < DIRECTIONS; ++i, d = (d + 1) % DIRECTIONS) {
					if (!is_water(map, x + MOVES[d][0], y + MOVES[d][1])) break;
				}
				if (ox == -1 && oy == -1) { // is it the first step?
					ox = x;
					oy = y;
					od = d;
				} else {
					if (x == ox && y == oy && d == od) break; // walked around once
				}
				x += MOVES[d][0];
				y += MOVES[d][1];
				if (!is_waterLeft(map, x, y, d)) { // no water on the left-> turn left
					d = (d - 1 + DIRECTIONS) % DIRECTIONS;
				}
			} while (true); 
			result.push_back(perimeter);
		} else if(is_water(map, x, y)) { // it's water
			if (is_within_map(map, x, y)) {
				map[x][y] = 2; // visited water
			}
			if (is_within_map(map, x, y + 1)) { // move further right
				s.push_front({ x, y + 1 });
			}
		}
	}
	return result;
}

int main()
{

	vector<vector<int>> map{
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
		{0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, },
		{0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, },
		{0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, },
		{0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
		{0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
		{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, },
		{0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, },
		{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, },
	};

	cout << "before:" << endl << map << endl << endl;
	cout << "result:" << calc_perimeter(map) << endl;
	cout << "after:" << endl << map << endl << endl;
}

/* output
before:
{
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
{0,1,0,0,0,1,1,1,0,0,1,1,1,1,1,0,0,1}
{0,0,0,1,0,1,0,1,0,0,0,1,1,1,1,0,0,1}
{0,0,0,0,0,1,0,1,0,0,0,0,0,1,1,0,0,1}
{0,1,1,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1}
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
{0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,1,0}
{0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,0,0}
{0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0}
}

result:{1,4,5,1,10,10,23,3}
after:
{
{2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}
{2,3,2,2,2,3,3,3,2,2,3,3,3,3,3,2,2,3}
{2,2,2,3,2,3,2,3,2,2,2,3,3,3,3,2,2,3}
{2,2,2,2,2,3,2,3,2,2,2,2,2,3,3,2,2,3}
{2,3,3,2,2,3,3,3,2,3,3,3,3,3,3,3,3,3}
{2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}
{2,2,2,2,2,2,2,2,3,2,2,2,3,2,2,3,3,2}
{2,3,3,3,3,3,2,2,3,3,3,3,3,2,2,3,2,2}
{2,2,2,2,2,2,2,2,3,3,2,3,2,2,2,2,2,2}
}
*/

bool is_within_map(vector<vector<int>>& map, int x, int y)
{
	return (static_cast<unsigned int>(x) < map.size() 
		&& static_cast<unsigned int>(y) < map[x].size());
}

bool is_unvisited_land(vector<vector<int>>& map, int x, int y)
{
	return is_within_map(map, x, y) && map[x][y] == 1;
}

bool is_water(vector<vector<int>>& map, int x, int y)
{
	return !is_within_map(map, x, y) || map[x][y] == 0 || map[x][y] == 2; // visited or unvisited water
}

bool is_unvisited_water(vector<vector<int>>& map, int x, int y)
{
	return is_within_map(map, x, y) && map[x][y] == 0;
}

bool is_waterLeft(vector<vector<int>>& map, int x, int y, int d)
{
	return is_water(map, x + LEFT_FIELD[d][0], y + LEFT_FIELD[d][1]);
}

ostream& operator <<(ostream& os, const vector<int>& v)
{
	os << "{";
	bool first = true;
	for (auto e : v) {
		if (!first) os << "," << e;
		else os << e;
		first = false;
	}
	os << "}";
	return os;
}

ostream& operator <<(ostream& os, const vector<vector<int>>& vv)
{
	os << "{" << endl;
	for (auto v : vv) {
		os << "  " << v << endl;
	}
	os << "}";
	return os;
}

- Chris November 08, 2017 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Python solution:

def islandParameter(matrix):

	def dfs(matrix, i, j):

		if i<0 or j<0 or i>=len(matrix) or j>=len(matrix[0]) or not matrix[i][j]:
			return 1

		if matrix[i][j]==-1:
			return 0

		matrix[i][j], ret = -1,0
		corrd = [(i+1,j),(i-1,j),(i,j+1),(i,j-1)]
		for corr in corrd:
			ret += dfs(matrix, corr[0], corr[1])
		return ret

	res = 0 
	for i in range(len(matrix)):
		for j in range(len(matrix[0])):
			if matrix[i][j]:
				res += dfs(matrix,i,j)

	print('Islanda parameter : {}'.format(res))

def main():

	#islandParameter
	matrix = [[0,1,0,0],
 			  [1,1,1,0],
 			  [0,1,0,0],
 			  [1,1,0,0]]
 	#islandParameter(matrix)

- DyingLizard December 20, 2017 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

1. Count no of islands in the matrix.
2. If current cell is 1, increment neighbour_count for each down ==1 and right cell == 1
3. islands_counts*4 - neighbour_count*2 is your solution

- Somal February 23, 2018 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Such questions are never asked in a Facebook interview. This looks like a college assignment question, which this person is try to get answered for free.

- Chris November 21, 2017 | Flag Reply


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More