import java.util.ArrayList;
import java.util.List;
class MineSweeperAlgorithm {
// this minesweeper algorithm uses O(1) space complexity
// set verbose to false to hide the step-by-step loggging
private static final boolean verbose = false;
private static int stepCount = 1;
public static void main
(String[] args
) { MineSweeperAlgorithm ins = new MineSweeperAlgorithm();
int[][] matrix;
// make a test case
stepCount = 1;
matrix = new int[5][];
matrix[0] = new int[]{0, 0, 1, 1, 1};
matrix[1] = new int[]{0, 1, 1, 1, 1};
matrix[2] = new int[]{0, 1, 0, 0, 1};
matrix[3] = new int[]{0, 0, 0, 0, 1};
matrix[4] = new int[]{0, 0, 0, 0, 1};
// run the test
System.
out.
println("Result is " + ins.validate(matrix, matrix.length, matrix[0].length));
}
public boolean validate(int[][] matrix, int m, int n) {
Pos nextStep = findZero(matrix, m, n);
if (nextStep == null) {
// the matrix deos not contain 0
return false;
}
// visit the first position, and go from there
matrix[nextStep.x][nextStep.y] = 2;
while (nextStep != null) {
nextStep = step(matrix, nextStep, m, n);
}
// after visiting all positions, check if there is remaining 0s
return findZero(matrix, m, n) == null;
}
Pos step(int[][] matrix, Pos cur, int m, int n) {
// Now cur is located at a pos with value = 2
// print matrix in "verbose" mode
if (verbose) {
System.
out.
println("Step #" + stepCount
++); for (int[] array : matrix) {
for (int num : array) {
}
}
}
// make a list of valid neighbors, for the convenience of checking
List<Pos> neighbors = new ArrayList<Pos>();
neighbors.add(new Pos(cur.x - 1, cur.y));
neighbors.add(new Pos(cur.x + 1, cur.y));
neighbors.add(new Pos(cur.x, cur.y - 1));
neighbors.add(new Pos(cur.x, cur.y + 1));
for (int i = neighbors.size() - 1; i >= 0; i--) {
if (!isValidPos(neighbors.get(i), m, n)) {
neighbors.remove(i);
}
}
// check if there is adjacent 0,
// if there is, mark 0 as 2 and return that position
for (Pos neighbor : neighbors) {
if (matrix[neighbor.x][neighbor.y] == 0) {
matrix[neighbor.x][neighbor.y] = 2;
return neighbor;
}
}
// if no adjacent 0, then check if there is adjacent 2.
// if there is, mark current as 3 and then return that position
for (Pos neighbor : neighbors) {
if (matrix[neighbor.x][neighbor.y] == 2) {
matrix[cur.x][cur.y] = 3;
return neighbor;
}
}
//if no adjacent 0 and no adjacent 2, mark current as 3 and return null
matrix[cur.x][cur.y] = 3;
return null;
}
boolean isValidPos(Pos p, int m, int n) {
return p.x >= 0 && p.x < m && p.y >= 0 && p.y < n;
}
Pos findZero(int[][] matrix, int m, int n) {
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == 0) {
return new Pos(i, j);
}
}
}
return null;
}
class Pos {
int x;
int y;
public Pos(int a, int b) {
x = a;
y = b;
}
}
}
ICAgIGltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwogICAgaW1wb3J0IGphdmEudXRpbC5MaXN0OwogICAgCiAgICBjbGFzcyBNaW5lU3dlZXBlckFsZ29yaXRobSB7CiAgICAKICAgICAgICAvLyB0aGlzIG1pbmVzd2VlcGVyIGFsZ29yaXRobSB1c2VzIE8oMSkgc3BhY2UgY29tcGxleGl0eQogICAgCiAgICAgICAgLy8gc2V0IHZlcmJvc2UgdG8gZmFsc2UgdG8gaGlkZSB0aGUgc3RlcC1ieS1zdGVwIGxvZ2dnaW5nCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiB2ZXJib3NlID0gZmFsc2U7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgaW50IHN0ZXBDb3VudCA9IDE7CiAgICAKICAgICAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CiAgICAgICAgICAgIE1pbmVTd2VlcGVyQWxnb3JpdGhtIGlucyA9IG5ldyBNaW5lU3dlZXBlckFsZ29yaXRobSgpOwogICAgCiAgICAgICAgICAgIGludFtdW10gbWF0cml4OwogICAgICAgICAgICAvLyBtYWtlIGEgdGVzdCBjYXNlCiAgICAgICAgICAgIHN0ZXBDb3VudCA9IDE7CiAgICAgICAgICAgIG1hdHJpeCA9IG5ldyBpbnRbNV1bXTsKICAgICAgICAgICAgbWF0cml4WzBdID0gbmV3IGludFtdezAsIDAsIDEsIDEsIDF9OwogICAgICAgICAgICBtYXRyaXhbMV0gPSBuZXcgaW50W117MCwgMSwgMSwgMSwgMX07CiAgICAgICAgICAgIG1hdHJpeFsyXSA9IG5ldyBpbnRbXXswLCAxLCAwLCAwLCAxfTsKICAgICAgICAgICAgbWF0cml4WzNdID0gbmV3IGludFtdezAsIDAsIDAsIDAsIDF9OwogICAgICAgICAgICBtYXRyaXhbNF0gPSBuZXcgaW50W117MCwgMCwgMCwgMCwgMX07CiAgICAKICAgICAgICAgICAgLy8gcnVuIHRoZSB0ZXN0CiAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUmVzdWx0IGlzICIgKwogICAgICAgICAgICAgICAgICAgIGlucy52YWxpZGF0ZShtYXRyaXgsIG1hdHJpeC5sZW5ndGgsIG1hdHJpeFswXS5sZW5ndGgpKTsKICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7CiAgICAgICAgfQogICAgCiAgICAgICAgcHVibGljIGJvb2xlYW4gdmFsaWRhdGUoaW50W11bXSBtYXRyaXgsIGludCBtLCBpbnQgbikgewogICAgICAgICAgICBQb3MgbmV4dFN0ZXAgPSBmaW5kWmVybyhtYXRyaXgsIG0sIG4pOwogICAgICAgICAgICBpZiAobmV4dFN0ZXAgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgLy8gdGhlIG1hdHJpeCBkZW9zIG5vdCBjb250YWluIDAKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgCiAgICAgICAgICAgIC8vIHZpc2l0IHRoZSBmaXJzdCBwb3NpdGlvbiwgYW5kIGdvIGZyb20gdGhlcmUKICAgICAgICAgICAgbWF0cml4W25leHRTdGVwLnhdW25leHRTdGVwLnldID0gMjsKICAgICAgICAgICAgd2hpbGUgKG5leHRTdGVwICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIG5leHRTdGVwID0gc3RlcChtYXRyaXgsIG5leHRTdGVwLCBtLCBuKTsKICAgICAgICAgICAgfQogICAgCiAgICAgICAgICAgIC8vIGFmdGVyIHZpc2l0aW5nIGFsbCBwb3NpdGlvbnMsIGNoZWNrIGlmIHRoZXJlIGlzIHJlbWFpbmluZyAwcwogICAgICAgICAgICByZXR1cm4gZmluZFplcm8obWF0cml4LCBtLCBuKSA9PSBudWxsOwogICAgICAgIH0KICAgIAogICAgICAgIFBvcyBzdGVwKGludFtdW10gbWF0cml4LCBQb3MgY3VyLCBpbnQgbSwgaW50IG4pIHsKICAgICAgICAgICAgLy8gTm93IGN1ciBpcyBsb2NhdGVkIGF0IGEgcG9zIHdpdGggdmFsdWUgPSAyCiAgICAgICAgICAgIC8vIHByaW50IG1hdHJpeCBpbiAidmVyYm9zZSIgbW9kZQogICAgICAgICAgICBpZiAodmVyYm9zZSkgewogICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJTdGVwICMiICsgc3RlcENvdW50KyspOwogICAgICAgICAgICAgICAgZm9yIChpbnRbXSBhcnJheSA6IG1hdHJpeCkgewogICAgICAgICAgICAgICAgICAgIGZvciAoaW50IG51bSA6IGFycmF5KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQobnVtICsgIiAiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKICAgICAgICAgICAgfQogICAgCiAgICAgICAgICAgIC8vIG1ha2UgYSBsaXN0IG9mIHZhbGlkIG5laWdoYm9ycywgZm9yIHRoZSBjb252ZW5pZW5jZSBvZiBjaGVja2luZwogICAgICAgICAgICBMaXN0PFBvcz4gbmVpZ2hib3JzID0gbmV3IEFycmF5TGlzdDxQb3M+KCk7CiAgICAgICAgICAgIG5laWdoYm9ycy5hZGQobmV3IFBvcyhjdXIueCAtIDEsIGN1ci55KSk7CiAgICAgICAgICAgIG5laWdoYm9ycy5hZGQobmV3IFBvcyhjdXIueCArIDEsIGN1ci55KSk7CiAgICAgICAgICAgIG5laWdoYm9ycy5hZGQobmV3IFBvcyhjdXIueCwgY3VyLnkgLSAxKSk7CiAgICAgICAgICAgIG5laWdoYm9ycy5hZGQobmV3IFBvcyhjdXIueCwgY3VyLnkgKyAxKSk7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSBuZWlnaGJvcnMuc2l6ZSgpIC0gMTsgaSA+PSAwOyBpLS0pIHsKICAgICAgICAgICAgICAgIGlmICghaXNWYWxpZFBvcyhuZWlnaGJvcnMuZ2V0KGkpLCBtLCBuKSkgewogICAgICAgICAgICAgICAgICAgIG5laWdoYm9ycy5yZW1vdmUoaSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgIAogICAgICAgICAgICAvLyBjaGVjayBpZiB0aGVyZSBpcyBhZGphY2VudCAwLAogICAgICAgICAgICAvLyBpZiB0aGVyZSBpcywgbWFyayAwIGFzIDIgYW5kIHJldHVybiB0aGF0IHBvc2l0aW9uCiAgICAgICAgICAgIGZvciAoUG9zIG5laWdoYm9yIDogbmVpZ2hib3JzKSB7CiAgICAgICAgICAgICAgICBpZiAobWF0cml4W25laWdoYm9yLnhdW25laWdoYm9yLnldID09IDApIHsKICAgICAgICAgICAgICAgICAgICBtYXRyaXhbbmVpZ2hib3IueF1bbmVpZ2hib3IueV0gPSAyOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZWlnaGJvcjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgCiAgICAgICAgICAgIC8vIGlmIG5vIGFkamFjZW50IDAsIHRoZW4gY2hlY2sgaWYgdGhlcmUgaXMgYWRqYWNlbnQgMi4KICAgICAgICAgICAgLy8gaWYgdGhlcmUgaXMsIG1hcmsgY3VycmVudCBhcyAzIGFuZCB0aGVuIHJldHVybiB0aGF0IHBvc2l0aW9uCiAgICAgICAgICAgIGZvciAoUG9zIG5laWdoYm9yIDogbmVpZ2hib3JzKSB7CiAgICAgICAgICAgICAgICBpZiAobWF0cml4W25laWdoYm9yLnhdW25laWdoYm9yLnldID09IDIpIHsKICAgICAgICAgICAgICAgICAgICBtYXRyaXhbY3VyLnhdW2N1ci55XSA9IDM7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5laWdoYm9yOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAKICAgICAgICAgICAgLy9pZiBubyBhZGphY2VudCAwIGFuZCBubyBhZGphY2VudCAyLCBtYXJrIGN1cnJlbnQgYXMgMyBhbmQgcmV0dXJuIG51bGwKICAgICAgICAgICAgbWF0cml4W2N1ci54XVtjdXIueV0gPSAzOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAKICAgICAgICBib29sZWFuIGlzVmFsaWRQb3MoUG9zIHAsIGludCBtLCBpbnQgbikgewogICAgICAgICAgICByZXR1cm4gcC54ID49IDAgJiYgcC54IDwgbSAmJiBwLnkgPj0gMCAmJiBwLnkgPCBuOwogICAgICAgIH0KICAgIAogICAgICAgIFBvcyBmaW5kWmVybyhpbnRbXVtdIG1hdHJpeCwgaW50IG0sIGludCBuKSB7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbTsgaSsrKSB7CiAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IG47IGorKykgewogICAgICAgICAgICAgICAgICAgIGlmIChtYXRyaXhbaV1bal0gPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFBvcyhpLCBqKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgCiAgICAgICAgY2xhc3MgUG9zIHsKICAgICAgICAgICAgaW50IHg7CiAgICAgICAgICAgIGludCB5OwogICAgCiAgICAgICAgICAgIHB1YmxpYyBQb3MoaW50IGEsIGludCBiKSB7CiAgICAgICAgICAgICAgICB4ID0gYTsKICAgICAgICAgICAgICAgIHkgPSBiOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQ==