Google Interview Question for SDE1s


Country: United States




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

package google;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

public class FindPath {

	public static class Point {
		int x;
		int y;

		public Point(int x, int y) {
			super();
			this.x = x;
			this.y = y;
		}

		@Override
		public boolean equals(Object o) {

			if (o == this)
				return true;
			if (!(o instanceof Point)) {
				return false;
			}
			Point point = (Point) o;
			return x == point.x && y == point.y;
		}

		@Override
		public int hashCode() {
			return Objects.hash(x, y);
		}
	}

	public static void main(String args[]) {
		char[][] board2 = { { '0', '2', '1', '1', '1' }, { '0', '1', 'a', '0', 'A' }, { '0', '1', '0', '0', '3' },
				{ '0', '1', '0', '0', '1' }, { '0', '1', '1', '1', '1' } };

		List<int[]> solution = solve(board2);
		for (int[] pos : solution) {
			System.out.println(Arrays.toString(pos));
		}
	}

	public static List<int[]> solve(char[][] board) {
		Point start = null;
		Point goal = null;
		HashSet<Point> visited = new HashSet<Point>();

		for (int i = 0; i < board.length; i++) {
			for (int j = 0; j < board[0].length; j++) {
				if (board[i][j] == '2') {
					start = new Point(i, j);
				} else if (board[i][j] == '3') {
					goal = new Point(i, j);
				}
			}
		}

		return solve(start, board, visited, goal, new LinkedList<int[]>(), new HashSet<Character>());
	}

	private static List<int[]> solve(Point cur, char[][] board, HashSet<Point> visited, Point goal,
			LinkedList<int[]> solution, HashSet<Character> keys) {

		if (cur.equals(goal)) {
			return (LinkedList<int[]>) solution.clone();
		}

		if (Character.isLowerCase(board[cur.x][cur.y])) {
			keys.add(board[cur.x][cur.y]);
		}

		visited.add(new Point(cur.x,cur.y));

		int i = cur.x;
		int j = cur.y;

		solution.add(new int[] { i, j });

		List<int[]> up = null;
		List<int[]> down = null;
		List<int[]> left = null;
		List<int[]> right = null;

		if (i - 1 >= 0 && board[i - 1][j] != '0' && !visited.contains(new Point(i - 1, j))
				&& isOpenableIfDoor(board, i - 1, j, keys)) {
			cur.x -= 1;
			up = solve(cur, board, visited, goal, solution, keys);
			cur.x += 1;
		}
		if (i + 1 < board.length && board[i + 1][j] != '0' && !visited.contains(new Point(i + 1, j))
				&& isOpenableIfDoor(board, i + 1, j, keys)) {
			cur.x += 1;
			down = solve(cur, board, visited, goal, solution, keys);
			cur.x -= 1;
		}
		if (j - 1 >= 0 && board[i][j - 1] != '0' && !visited.contains(new Point(i, j - 1))
				&& isOpenableIfDoor(board, i, j - 1, keys)) {
			cur.y -= 1;
			left = solve(cur, board, visited, goal, solution, keys);
			cur.y += 1;
		}
		if (j + 1 < board[0].length && board[i][j + 1] != '0' && !visited.contains(new Point(i, j + 1))
				&& isOpenableIfDoor(board, i, j + 1, keys)) {
			cur.y += 1;
			right = solve(cur, board, visited, goal, solution, keys);
			cur.y -= 1;
		}

		List<List<int[]>> res = new LinkedList<List<int[]>>();
		res.add(up);
		res.add(down);
		res.add(left);
		res.add(right);
		Collections.sort(res, new Comparator<List<int[]>>() {

			@Override
			public int compare(List<int[]> arg0, List<int[]> arg1) {
				if (arg0 != null && arg1 != null) {
					return Integer.compare(arg0.size(), arg1.size());
				} else if (arg0 != null) {
					return -1;
				} else if (arg1 != null) {
					return 1;
				} else {
					return 0;
				}
			}
		});
		if (Character.isLowerCase(board[cur.x][cur.y])) {
			keys.remove(board[cur.x][cur.y]);
		}
		solution.removeLast();
		visited.remove(new Point(i, j));
		return res.get(0);
	}

	private static boolean isOpenableIfDoor(char[][] board, int i, int j, HashSet<Character> keys) {
		if (Character.isUpperCase(board[i][j])) {
			if (keys.contains(Character.toLowerCase(board[i][j]))) {
				return true;
			}
			return false;
		}
		return true;
	}
}

- Dhruva.Bharadwaj May 16, 2017 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

1. Identify special nodes in matrix ("2", "3", "a", "A" ...)
2. Build graph for these special node (BFS for node edges)
3. Find shortest path from "2" to "3" in the graph
Simple BFS shortest path algorithm does not work since path has dependency
Use DFS to find shortest path, easy to check key->door dependency
4. Reconstruct path

import sys
"""
'0' : water
'1' : land (can walk)
'a' : key of 'A'
'A' : door require key 'a'
"""
def get_path(prev, i, j):
    path = []
    path.append((i, j))
    while prev[i][j] != (-1, -1):
        i, j = prev[i][j]
        path.append((i, j))
    path.pop() # pop src idx
    return path[::-1]
    
    
def get_edges(matrix, s_node, src, t_node):
    bfs = collections.deque([src, (None, None)])
    parent = [[None]*len(matrix[0]) for _ in xrange(len(matrix))]
    parent[src[0]][src[1]] = (-1, -1)
    d = 1
    edge = {}
    while bfs:
        i, j = bfs.popleft()
        if i == None:
            d += 1
            if bfs:
                bfs.append((None, None))
        else:
            for n_i, n_j in ((i+1, j), (i-1, j), (i, j+1), (i, j-1)):
                if (0 <= n_i < len(matrix) and 0 <= n_j < len(matrix[0]) and 
                    parent[n_i][n_j] == None):
                    parent[n_i][n_j] = (i, j)
                    if matrix[n_i][n_j] in t_node:
                        edge[matrix[n_i][n_j]] = get_path(parent, n_i, n_j)
                        if len(edge) == len(t_node) - 1:
                            break
                    elif matrix[n_i][n_j] == "1":
                        bfs.append((n_i, n_j))
    return edge

def shortest_path(path, cost, node, dst, result):
    if path[-1] == dst:
        print(path, cost)
        if cost < result[0]:
            result[0] = cost
            result[1] = path[:]
        return
    cur = path[-1]
    for ne in node[cur].keys():
        if ne not in path:
            if (ord("A") <= ord(ne) <= ord("Z") and 
                chr(ord(ne) - ord("A") + ord("a")) not in path):
                continue
            next_cost = cost + len(node[cur][ne])
            if next_cost >= result[0]:
                continue
            path.append(ne)
            shortest_path(path, cost + len(node[cur][ne]), node, dst, result)
            path.pop()
    

def key_path(matrix):
    # 1. find all special node
    # 2. Build graph of all special node (search shortest path between nodes)
    # 3. Find shortest path of the graph (DFS)
    
    # 1. find all nodes
    node = {}
    node_pos = {}
    for i in xrange(len(matrix)):
        for j in xrange(len(matrix[0])):
            if matrix[i][j] not in ['0', '1']:
                node[matrix[i][j]] = {}
                node_pos[matrix[i][j]] = (i,j)
    
    # 2. find edge of nodes
    for n in node.keys():
        node[n] = get_edges(matrix, n, node_pos[n], node.keys())
        
    # 3. do shortest path from src to dst
    #path = shortest_path(node, "2", "3")
    result = [sys.maxint, []]
    shortest_path(["2"], 0, node, "3", result)
    path = result[1]
    print(path)
    
    # combine path
    total_path = [node_pos["2"]]
    for i in xrange(1, len(path)):
        total_path += node[path[i-1]][path[i]]
    
    print(total_path)
    return total_path
    
matrix = [["0", "2", "1", "1", "1"],
          ["0", "1", "a", "C", "0"],
          ["0", "1", "b", "B", "1"],
          ["1", "1", "c", "0", "3"],
          ["0", "A", "1", "1", "1"]]

key_path(matrix)

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

1. Identify special nodes in matrix ("2", "3", "a", "A" ...)
2. Build graph for these special node (BFS for node edges)
3. Find shortest path from "2" to "3" in the graph
Simple BFS shortest path algorithm does not work since path has dependency
Use DFS to find shortest path, easy to check key->door dependency
4. Reconstruct path

import sys
"""
'0' : water
'1' : land (can walk)
'a' : key of 'A'
'A' : door require key 'a'
"""
def get_path(prev, i, j):
    path = []
    path.append((i, j))
    while prev[i][j] != (-1, -1):
        i, j = prev[i][j]
        path.append((i, j))
    path.pop() # pop src idx
    return path[::-1]
    
    
def get_edges(matrix, s_node, src, t_node):
    bfs = collections.deque([src, (None, None)])
    parent = [[None]*len(matrix[0]) for _ in xrange(len(matrix))]
    parent[src[0]][src[1]] = (-1, -1)
    d = 1
    edge = {}
    while bfs:
        i, j = bfs.popleft()
        if i == None:
            d += 1
            if bfs:
                bfs.append((None, None))
        else:
            for n_i, n_j in ((i+1, j), (i-1, j), (i, j+1), (i, j-1)):
                if (0 <= n_i < len(matrix) and 0 <= n_j < len(matrix[0]) and 
                    parent[n_i][n_j] == None):
                    parent[n_i][n_j] = (i, j)
                    if matrix[n_i][n_j] in t_node:
                        edge[matrix[n_i][n_j]] = get_path(parent, n_i, n_j)
                        if len(edge) == len(t_node) - 1:
                            break
                    elif matrix[n_i][n_j] == "1":
                        bfs.append((n_i, n_j))
    return edge

def shortest_path(path, cost, node, dst, result):
    if path[-1] == dst:
        print(path, cost)
        if cost < result[0]:
            result[0] = cost
            result[1] = path[:]
        return
    cur = path[-1]
    for ne in node[cur].keys():
        if ne not in path:
            if (ord("A") <= ord(ne) <= ord("Z") and 
                chr(ord(ne) - ord("A") + ord("a")) not in path):
                continue
            next_cost = cost + len(node[cur][ne])
            if next_cost >= result[0]:
                continue
            path.append(ne)
            shortest_path(path, cost + len(node[cur][ne]), node, dst, result)
            path.pop()
    

def key_path(matrix):
    # 1. find all special node
    # 2. Build graph of all special node (search shortest path between nodes)
    # 3. Find shortest path of the graph (DFS)
    
    # 1. find all nodes
    node = {}
    node_pos = {}
    for i in xrange(len(matrix)):
        for j in xrange(len(matrix[0])):
            if matrix[i][j] not in ['0', '1']:
                node[matrix[i][j]] = {}
                node_pos[matrix[i][j]] = (i,j)
    
    # 2. find edge of nodes
    for n in node.keys():
        node[n] = get_edges(matrix, n, node_pos[n], node.keys())
        
    # 3. do shortest path from src to dst
    #path = shortest_path(node, "2", "3")
    result = [sys.maxint, []]
    shortest_path(["2"], 0, node, "3", result)
    path = result[1]
    print(path)
    
    # combine path
    total_path = [node_pos["2"]]
    for i in xrange(1, len(path)):
        total_path += node[path[i-1]][path[i]]
    
    print(total_path)
    return total_path
    
matrix = [["0", "2", "1", "1", "1"],
          ["0", "1", "a", "C", "0"],
          ["0", "1", "b", "B", "1"],
          ["1", "1", "c", "0", "3"],
          ["0", "A", "1", "1", "1"]]

key_path(matrix)

- MFJhang November 05, 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