黑白翻转棋
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 42 ms, 内存: 16.0 MB
/*
* 思路:
* 使用 Java Stream 来简化代码流程,依然是遍历所有空位并计算最多翻转的棋子数。
* 使用 List 存储所有可能的翻转数量,最后取最大值。
*/
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class FlipChessStream {
private static final int[][] DIRECTIONS = {
{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {-1, -1}, {1, -1}, {-1, 1}
};
public int maxFlip(String[] chessboard) {
return Arrays.stream(chessboard)
.flatMapToInt(row -> Arrays.stream(row.split("")))
.collect(Collectors.toList())
.stream()
.mapToInt(ch -> chessboard.length * chessboard[0].length())
.map(idx -> {
int x = idx / chessboard[0].length();
int y = idx % chessboard[0].length();
return chessboard[x].charAt(y) == '.' ? countFlips(chessboard, x, y) : 0;
})
.max().orElse(0);
}
private int countFlips(String[] board, int x, int y) {
return Arrays.stream(DIRECTIONS)
.mapToInt(dir -> flipDirection(board, x, y, dir[0], dir[1]))
.sum();
}
private int flipDirection(String[] board, int x, int y, int dx, int dy) {
int nx = x + dx, ny = y + dy;
int flipCount = 0;
boolean canFlip = false;
while (nx >= 0 && nx < board.length && ny >= 0 && ny < board[0].length()) {
if (board[nx].charAt(ny) == '.') break;
if (board[nx].charAt(ny) == 'X') {
canFlip = true;
break;
}
flipCount++;
nx += dx;
ny += dy;
}
return canFlip ? flipCount : 0;
}
}
解释
方法:
这个题解的思路是通过模拟下棋的过程来寻找最优的下棋位置。首先,遍历棋盘上的每一个空位('.'),尝试在这个位置放置黑棋('X'),然后从这个位置向八个方向(上、下、左、右、四个对角线方向)探索,查看是否可以通过放置这个棋子来翻转周围的白棋('O')。如果在某个方向上,从当前位置出发,连续遇到白棋后再遇到一个黑棋,那么这一路上的所有白棋都可以被翻转成黑棋。每次模拟下棋后,计算可以翻转的白棋数量,并更新最大值。最后返回最大的翻转数量。
时间复杂度:
O(n^4)
空间复杂度:
O(n^2)
代码细节讲解
🦆
在这个算法中,如果棋盘的大小变得更大,这种模拟方法的效率会如何变化?
▷🦆
在模拟过程中,为什么选择在一个方向上如果遇到白棋后又遇到黑棋就进行翻转,这是否确保了翻转的合法性?
▷🦆
算法中使用了一个队列来存储可能被翻转的棋子位置,这个队列的作用是什么,是否有其他数据结构可以替代来提高效率?
▷