Google Interview Question for Software Engineer / Developers


Country: United States
Interview Type: Phone Interview




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

def bucketfill(image,newcolor,x,y):
   width=len(image)
   height=len(image[0])
   oldcolor=image[x][y]
   if oldcolor==newcolor: return #added because of eugene's reply
   image[x][y]=newcolor
   if x>0:
      if image[x-1][y]==oldcolor: bucketfill(image,newcolor,x-1,y)
   if y>0:
      if image[x][y-1]==oldcolor: bucketfill(image,newcolor,x,y-1)
   if x<width-1:
      if image[x+1][y]==oldcolor: bucketfill(image,newcolor,x+1,y)
   if y<height-1:
      if image[x][y+1]==oldcolor: bucketfill(image,newcolor,x,y+1)
   return

- skeptical.scientist January 05, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

You get into infinite recursion here if oldColor ==
newColor. I would add a quick explicit check for that condition.

- eugene.yarovoi January 05, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Good point.

- skeptical.scientist January 05, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Good approach. I think, checking diagonally across will be more complete. Thoughts?

- Anonymous January 06, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Isn't this exactly how one would implement flood-fill algorithm?

- Nishant January 13, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

use a linefill approach much faster..
start with (x,y) extend to [L,R] where L & R are left and right extreme on the monochromatic extensions.
then construct lines top and bottom of this line which are monochromatic extensions
this one will fill as lines and will beat the above algorithm in complexity as you are visiting every point 8 times

- kkr.ashish February 20, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

ashish, I don't see how that is faster. In order to find L and R, you need to scan the image one pixel at a time in both directions to see if there's an interruption. (Unless there's a better way I'm not seeing?) But if you do this, you might as well color each pixel as you go, which is essentially the same thing as this algorithm is doing.

- Anonymous February 20, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@above
Hello,
please have a look in this way
i am at (x,y) i will check (x-1,y) ,(x,y-1),(x+1,y) ,(x,y+1) and not necessarily in this order.. but all of these will be checked
i sure have made (x,y) as new color but when i am at(x-1,y) i am still going to check (x,y),(x-1,y-1),(x-1,y+1),(x-2,y) because still the if statement needs to run so this is redundant check.. but if i know from [1,15] all are newcolor at given y-coordinate .. i dont need to check those coordinate again rather i will be looking at (y-1) coordinate points [1,15] and then left and right extend to get the new Line[L,R] at y-1 coordinate and same way the y + 1 direction.

- kkr.ashish February 20, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include <iostream>
#include <cstdlib>
using namespace std;

class BucketFill
{
    const int m_XLen;
    const int m_YLen;
    int* m_bitmap;
    int m_oldColor;
    int m_newColor;
    int& Color(int x, int y)
    {
        return m_bitmap[x * m_YLen + y];
    }
    typedef int Direction; // N = 0, NE = 1, E = 2, SE = 3, S = 4, SW = 5, W = 6, NW = 7, NOWHERE = 8
    static const int NOWHERE = 8;
    Direction Opposite(Direction d)
    {
        if (d >= 0 && d < NOWHERE)
            return (d + 4) % 8;
        else
            return NOWHERE;
    }
    Direction FindNext(int x, int y)
    {
        for (Direction d = 0; d <= 7; ++d)
        {
            int xx = x;
            int yy = y;
            if (Move(xx, yy, d) && Color(xx, yy) == m_oldColor)
                return d;
        }
        return NOWHERE;
    }
    bool Move(int& x, int& y, Direction d)
    {
        int xx = x;
        int yy = y;
        switch (d)
        {
            case 0:       --yy; break; // N
            case 1: ++xx; --yy; break; // NE
            case 2: ++xx;       break; // E
            case 3: ++xx; ++yy; break; // SE
            case 4:       ++yy; break; // S
            case 5: --xx; ++yy; break; // SW
            case 6: --xx;       break; // W
            case 7: --xx; --yy; break; // NW
            default:            break; // NOWHERE
        }
        if (xx >= 0 && xx < m_XLen && yy >= 0 && yy < m_YLen)
        {
            x = xx;
            y = yy;
            return true;
        }
        return false;
    }
    int Base()
    {
        return ~m_oldColor & 0xFF;
    }
    void SetPrevDirection(int x, int y, Direction d)
    {
        Color(x, y) = Base() + d;
    }
    Direction GetPrevDirection(int x, int y)
    {
        return Color(x, y) - Base();
    }
    bool FillSome(int& x, int& y)
    {
        Direction d = FindNext(x, y);
        if (d != NOWHERE)
        {
            Move(x, y, d);
            SetPrevDirection(x, y, Opposite(d));
        }
        else
        {
            const Direction d = GetPrevDirection(x, y);
            Color(x, y) = m_newColor;
            if (d == NOWHERE)
                return false;
            Move(x, y, d);
        }
        return true;
    }
public:
    BucketFill(int* bitmap, int XLen, int YLen)
        : m_bitmap(bitmap)
        , m_XLen(XLen)
        , m_YLen(YLen)
    {}
    void Fill(int newColor, int x0, int y0)
    {
        m_newColor = newColor;
        m_oldColor = Color(x0, y0);
        SetPrevDirection(x0, y0, NOWHERE);
        while (FillSome(x0, y0))
            ;
    }
};
void Print(int* bitmap, int XLen, int YLen, const char* msg)
{
    cout << msg << endl;
    for (int y = 0; y < YLen; ++y)
    {
        for (int x = 0; x < XLen; ++x)
        {
            cout << (char)(bitmap[x * YLen + y] & 0xFF);
        }
        cout << endl;
    }
    cout << endl;
}
int main()
{
    const int oldColor = 'X';
    const int newColor = '+';
    const int otherColor = ' ';
    const int x0 = 0;
    const int y0 = 0;
    const int XLen = 40;
    const int YLen = 20;
    int bitmap[XLen][YLen] = {0};
    for (int x = 0; x < XLen; ++x)
        for (int y = 0; y < YLen; ++y)
        {
            const bool isOld = rand() < RAND_MAX / 2;
            bitmap[x][y] = isOld ? oldColor : otherColor;
        }
    Print(&bitmap[0][0], XLen, YLen, "before:");
    BucketFill bf(&bitmap[0][0], XLen, YLen);
    bf.Fill(newColor, x0, y0);
    Print(&bitmap[0][0], XLen, YLen, "after:");
    return 0;
}

- sgstep January 06, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote
public void changeColor(int[][] a, int newcolor, int oldcolor, int x, int y){ {{{ int row = a.length; {{{ int col = a[0].length; {{{ if(x-1>=0 && a[x-1][y] == oldcolor){ {{{{ a[x-1][y] = newcolor; {{{{ changeColor(a, newcolor, oldcolor,x-1,y); }}} } {{{ if(y+1<col && a[x][y+1] == oldcolor){ {{{{ a[x][y+1] = newcolor; {{{{ changeColor(a, newcolor, oldcolor,x,y+1); {{{ } {{{ if(x+1<row && a[x+1][y] == oldcolor){ {{{{ a[x+1][y] = newcolor; {{{{ changeColor(a, newcolor, oldcolor,x+1,y); }}} } {{{ if(y-1>=0 && a[x][y-1] == oldcolor){ {{{{ a[x][y-1] = newcolor; {{{{ changeColor(a, newcolor, oldcolor,x,y-1); }}} } }}} return; } - Anonymous January 09, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public void changeColor(int[][] a, int newcolor, int oldcolor, int x, int y){
		 int row = a.length;
		 int col = a[0].length;
		 
		 if(x-1>=0 && a[x-1][y] == oldcolor){
			 a[x-1][y] = newcolor;
			 changeColor(a, newcolor, oldcolor,x-1,y);
		 }
		 if(y+1<col && a[x][y+1] == oldcolor){
			 a[x][y+1] = newcolor;
			 changeColor(a, newcolor, oldcolor,x,y+1);
		 }
		 if(x+1<row && a[x+1][y] == oldcolor){
			 a[x+1][y] = newcolor;
			 changeColor(a, newcolor, oldcolor,x+1,y);
		 }
		 if(y-1>=0 && a[x][y-1] == oldcolor){
			 a[x][y-1] = newcolor;
			 changeColor(a, newcolor, oldcolor,x,y-1);
		 }
		 return;
	 }

- Anonymous January 09, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

struct Point{
int x;
int y;
};

void bucketfill(int newcolor, int x, int y, vector<vector<int> >& bitmap) {
Point direction[4] = {(-1 , 0), (0, -1), (0, 1), (1, 0)};
vector<Point> list;
Point s;
s.x = x;
s.y = y;
list.push_back(s);
int c = 0, color = bitmap[x][y];
bitmap[x][y] = newcolor;
while(c < list.size()){
for(int i = 0; i < 4; i++){
Point newp;
newp.x = list[c].x + direction[i].x;
newp.y = list[c].y + direction[i].y;
if(newp.x >=0 && newp.x < bitmap.size() && newp.y >= 0 && newp.y < bitmap[newp.x].size() && bitmap[newp.x][newp.y] == color){
list.push_back(newp);
bitmap[newp.x][newp.y] = newcolor;
}
}
c++;
}
}

- Anonymous January 11, 2013 | 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