Set Matrix Zeroes II

Image placeholder 9899Image placeholder 9899

(This question has been seen in the interviews of the following companies: Google, Facebook)
[Google Onsite Questions]

Set Matrix Zeroes II

There are orbs on an NxM board ('O' denotes orb. 'X' denotes empty slot).

Whenever two orbs are in the same column or the same row, you get to erase one of them.

Try to erase as many orbs as possible.

Find the minimum number of orbs remained on board eventually.

e.g.

        OXOXXO

        XXXXXO

        XXXXOX
    
erase (0,0) and get

        XXOXXO

        XXXXXO

        XXXXOX
    
erase (2,0) and get
        XXXXXO

        XXXXXO

        XXXXOX
    
erase (5,0) and get

        XXXXXX

        XXXXXO

        XXXXOX
    
no more moves available. Return 2 e.g.

        OXOXXO

        XXXXXO

        XXOXOX    

erase(4,2), (2,2), (0,0), (2,0), (5,0)

Return 1

e.g.

        OXOXXX

        XOXXXO

        XXXOOX
                

erase(0,0), (1,1), (3,2)

Return 3

Follow-up Build a solver for this board game that erases the as many orbs as possible.

Implementation

def solve(board):
    m, n = len(board), len(board[0])
    '''create adjacency list
    rows[0] has all the nodes in 1st row
    rows[1] has all the nodes in 2nd row
    etc.
    cols[0] has all the nodes in 1st column
    cols[1] has all the nodes in 2nd column
    etc.'''
    rows, cols = [set() for i in range(m)], [set() for j in range(n)]
    for i in range(m):
        for j in range(n):
            if board[i][j] is 'O':
                rows[i].add(j)
                cols[j].add(i)

    #count the degree (number of neighbors) of every orb
    degrees = dict()
    for i in range(m):
        for j in rows[i]:
            degree = len(rows[i]) + len(cols[j]) - 2
            if degree > 0:
                degrees[(i, j)] = degrees

    #erase the node with minimum positive degree until all nodes have 0 degree
    while degrees:
        erase_orb(degrees, board, rows, cols)

    #output
    for row in board:
        print row


#erase the orb with the minimum degree
def erase_orb(degrees, board, rows, cols):
    #find the node with minimum positive degree
    i, j = min(degrees.items(), key=lambda x: x[1])[0]
    #erase this node
    rows[i].remove(j)
    cols[j].remove(i)
    degrees.pop((i, j))
    board[i][j] = 'X'
    print 'erase ', (i, j)

    #remove one degree from every neighbor of the node erased
    for y in rows[i]:
        degrees[(i, y)] -= 1
        if degrees[(i, y)] is 0:
            degrees.pop((i, y))

    for x in cols[j]:
        degrees[(x, j)] -= 1
        if degrees[(x, j)] is 0:
            degrees.pop((x, j))



solve([
    ['X', 'X', 'X', 'X', 'X', 'O'],
    ['O', 'X', 'X', 'X', 'X', 'X'],
    ['O', 'X', 'X', 'X', 'X', 'O'],
    ['X', 'X', 'O', 'X', 'O', 'X'],
    ['X', 'O', 'X', 'X', 'X', 'O']
    ])



Get one-to-one training from Google Facebook engineers

Top-notch Professionals

Learn from Facebook and Google senior engineers interviewed 100+ candidates.
Most recent interview questions and system design topics gathered from aonecode alumnus.
One-to-one online classes. Get feedbacks from real interviewers.

Customized Private Class

Already a coding expert? - Advance straight to hard interview topics of your interest.
New to the ground? - Develop basic coding skills with your own designated mentor.
Days before interview? - Focus on most important problems in target company question bank.