I'm not 100% sure I understand what you want.
I'm imagining something like a labyrinth with multiple possible starting points on the outside edge, and you want to know all the possible areas that can be visited/filled from the outside?
The solution to make it more efficient is to cache values so that you don't go recalculating fills that were already calculated.
Make an other 2d array of equal size to keep track of already filled points.
Something like
byte[][] filledPoints = new byte[n][m];
initialized with 0
meaning unfilled.
Just for example:
final byte UNFILLED = 0;
final byte RED = 1;
final byte BLUE = 2;
When you do a fill, for each point you visit mark that point with a "fill-color" to say that it was already calculated.
Eg. filledPoints[0][1] = RED
BUT, when doing a fill, if the point you are starting on is already filled, then that whole fill that you are about to do has already been calculated by a previous fill.
if(filledPoints[x][y] != UNFILLED){
// Then this fill was already filled with the color of filledPoint[x][y]
}
So if it was already calculated then you don't need to calculate it again, so move on to the next starting point that you want to try to fill and check if that is already filled.
When you find a fill area that is not already filled, then start filling it with a new "color", and keep track of the area that gets filled.
Eg. filledPoints[0][386] = BLUE
The un-flood-fillable area is of course the total area minus the sum of all flood filled areas.