Java FloodFill Problem stack overflow error

Mridul Mittal :

I am trying to implement 4 way floodfill problem using java.
Flood Fill Algorithm Wikipedia

Problem:

I have this matrix

1 2 1
1 2 2
2 1 2

Now I will select element (0,1) of this matrix and apply flood fill problem to this to change all the 2's which satisfy my recursion condition to 3's.

My final matrix should be:

1 3 1
1 3 3
2 1 3

I have written a java code for the same but it gives me StackOverflow error. can anyone help me to figure out how to avoid it.

Here is my code:

import java.util.*;
public class abc {

static void printarray(int a[][])
{
    for ( int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
        {
            System.out.print(a[i][j]+ " ");
        }
        System.out.println();
    }

}
static void flood(int arr[][],int x,int y) {
    //base cases
    if (x < 0 || x >= 3 || y < 0 || y >= 3||arr[x][y] == 1) {
        return;
    }


    // i have made a dimension specific function but i can generalize it !.
    arr[x][y] = 3;
    flood(arr,x-1,y);
    flood(arr,x,y-1);
    flood(arr,x,y+1);
    flood(arr,x+1,y);
}

public static void main(String[] args) {
    int screen[][] = {
            {1, 2, 1},
        {1, 2,2},
        {2,1,2}
    };

    flood(screen,0,1);
    printarray(screen);
}

Error:

Exception in thread "main" java.lang.StackOverflowError
at java.base/sun.nio.cs.UTF_8.updatePositions(UTF_8.java:79)
at java.base/sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(UTF_8.java:509)
at java.base/sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:564)
at java.base/java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:576)
at java.base/sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:292)
at java.base/sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:281)
at java.base/sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
at java.base/java.io.OutputStreamWriter.write(OutputStreamWriter.java:211)
at java.base/java.io.BufferedWriter.flushBuffer(BufferedWriter.java:120)
at java.base/java.io.PrintStream.newLine(PrintStream.java:624)
at java.base/java.io.PrintStream.println(PrintStream.java:772)
at abc.flood(abc.java:19)
at abc.flood(abc.java:30)
at abc.flood(abc.java:30)
at abc.flood(abc.java:33)
at abc.flood(abc.java:30)
at abc.flood(abc.java:33)
Dillon Davis :

Your problem is on this line:

flood(arr,x-1,y);
flood(arr,x,y-1);
flood(arr,x,y+1);
flood(arr,x+1,y);

You unconditionally explore all 4 directions from the current cell in a depth-first search, which somewhere creates an infinite recursion loop as the search toggles between the same two tiles. To fix this, either

  • Keep track of explored cells, and don't revisit them
  • Do a breadth-first search instead of DFS
  • Do an iteratively-deepening depth-first search.

The easiest would be to modify the following line

if (x < 0 || x >= 3 || y < 0 || y >= 3||arr[x][y] == 1) {
    return;
}

To instead return if arr[x][y] != 2, this effectively implements option #1, by preventing you from exploring cells that have already been converted to 3, since 3 != 2 will cause it to return.

if (x < 0 || x >= 3 || y < 0 || y >= 3||arr[x][y] != 2) {
    return;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=106204&siteId=1