Durante un colloquio tecnico di 45 minuti con Google, mi è stato chiesto un problema con Leaper Graph. Ho scritto codice di lavoro, ma in seguito ho rifiutato l'offerta di lavoro perché mi mancava la conoscenza della struttura dei dati. Mi sto chiedendo cosa avrei potuto fare meglio.Ottimizza algoritmo Leaper Graph?
Il problema era come segue: "Dato un bordo di dimensioni N, e ha detto che un pezzo può saltare i posizioni orizzontale posizioni j (sinistra o destra) e verticalmente (su o giù) (Vale a dire, un po 'come un cavallo negli scacchi), il saltatore può raggiungere ogni punto del tabellone? "
Ho scritto il seguente algoritmo. Trova ricorsivamente se ogni posizione sulla scacchiera è raggiungibile segnando tutti i punti sul grafico che sono stati visitati. Se non era raggiungibile, almeno un campo era falso e la funzione restituiva false.
static boolean reachable(int i, int j, int n) {
boolean grid[][] = new boolean[n][n];
reachableHelper(0, 0, grid, i, j, n - 1);
for (int x = 0; x < n; x++) {
for (int y = 0; y < n; y++) {
if (!grid[x][y]) {
return false;
}
}
}
return true;
}
static void reachableHelper(int x, int y, boolean[][] grid, int i, int j, int max) {
if (x > max || y > max || x < 0 || y < 0 || grid[x][y]) {
return;
}
grid[x][y] = true;
int i2 = i;
int j2 = j;
for (int a = 0; a < 2; a++) {
for (int b = 0; b < 2; b++) {
reachableHelper(x + i2, y + j2, grid, i, j, max);
reachableHelper(x + j2, y + i2, grid, i, j, max);
i2 = -i2;
}
j2 = -j2;
}
}
Ora, in seguito è stato sottolineato che la soluzione ottimale sarebbe quella di implementare co-prime implementazione di Donald Knuth: http://arxiv.org/pdf/math/9411240v1.pdf E 'questo qualcosa che si dovrebbe essere in grado di capire da 45 minuti di colloquio tecnico? ?
Oltre a quanto sopra, c'è qualcosa che avrei potuto fare meglio?
modifica:
- Ho chiesto informazioni sulla posizione di partenza. Mi è stato detto che partire da 0,0 va bene.
edit2 In base al feedback, ho scritto un ciclo while con approccio in coda. L'approccio ricorsivo viene eseguito in un overflow dello stack quando n = 85. Tuttavia, il ciclo while con il metodo code in basso funziona fino a ~ n = 30.000. (dopo di ciò si verificano problemi di heap con memoria superiore a quella di GB). Se sai come ottimizzare ulteriormente, faccelo sapere.
static boolean isReachableLoop(int i, int j, int n) {
boolean [][] grid = new boolean [n][n];
LinkedList<Point> queue = new LinkedList<Point>();
queue.add(new Point(0,0)); // starting position.
int nodesVisited = 0;
while (queue.size() != 0) {
Point pos = queue.removeFirst();
if (pos.x >= 0 && pos.y >= 0 && pos.x < n && pos.y < n) {
if (!grid[pos.x][pos.y]) {
grid[pos.x][pos.y] = true;
nodesVisited++;
int i2 = i;
int j2 = j;
for (int a = 0; a < 2; a++) {
for (int b = 0; b < 2; b++) {
queue.add(new Point(pos.x+i2, pos.y+j2));
queue.add(new Point(pos.x+j2, pos.y+i2));
i2 = -i2;
}
j2 = -j2;
}
}
}
}
if (nodesVisited == (n * n)) {
return true;
} else {
return false;
}
}
Ti è stata assegnata una posizione di partenza? O devi scoprire tu stesso la posizione ottimale? – smac89
Ho interrogato l'intervistatore. Mi è stato detto che 0x0 era una posizione legittima. –
Se puoi raggiungere ovunque sul tabellone da * qualsiasi * posizione, allora puoi raggiungere ovunque sul tabellone da * ogni * posizione, quindi la posizione di partenza non è importante –