每一个格子代表一种地形,同时格子上可能有多个皇冠或没有。要求是计算一个score,score的计算方式是,先找到彼此连接的同种地形,
记录该块土地的面积(即几个格子)和该块土地上的总皇冠数,再对所有的面积和皇冠数之积,进行累加。表达式大概就是score = area0 * crown0 + area1 * crown1 + area2 * crown2...
Union Find的经典案列。比一般的UF的解法多的就是这里多了一个Crown的数量。
解法的办法就是UF里面再建一个Crown的数组, Union的时候把crown的数量也Union在一起。
还是比较直接的,没什么好说的。
我写的时候出了两个bug,
1。 UF constructor里面忘了新建那几个数组了。
2。 UF Union的时候 我忘了判断是不是本来root就是相等的了。这时一定要退出,否则会出错。
看代码,长是长了一点, 不过都是基本操作呀
UF基本功要打好。
public int calBoardGame(List<String> input) {
int N = input.size();
int M = input.get(0).split(" ").length;
char[][] board = new char[N][M];
int[][] crowns = new int[N][M];
for (int i = 0; i < N; i++) {
String[] line = input.get(i).split(" ");
for (int c = 0; c < M; c++) {
board[i][c] = line[c].charAt(0);
crowns[i][c] = line[c].charAt(1) - '0';
}
}
UnionFind uf = new UnionFind(N * M, crowns);
for (int row = 0; row < N; row++) {
for (int col = 0; col < M; col++) {
if (row > 0 && board[row - 1][col] == board[row][col]) {
uf.union(col + (row - 1) * M, col + (row) * M);
}
if (col > 0 && board[row][col - 1] == board[row][col]) {
uf.union(col - 1 + (row ) * M, col + (row) * M);
}
}
}
int sum = 0;
for (int i = 0; i < N * M; i++) {
if (uf.root(i) == i) {
sum += uf.getWeight(i) * uf.getCrown(i);
}
}
return sum;
}
class UnionFind{
int[] ids;
int[] weights;
int[] crowns;
public UnionFind(int n, int[][] crownBoard) {
int N = crownBoard.length, M = crownBoard[0].length;
ids = new int[N * M];
weights = new int[N * M];
crowns = new int[N * M];
for (int r = 0; r < N; r++) {
for (int c = 0; c < M; c++) {
ids[r * M + c] = r * M + c;
weights[r * M + c] = 1;
crowns[r * M + c] = crownBoard[r][c];
}
}
}
public int root(int id){
if (ids[id] != id) {
ids[id] = root(ids[id]);
}
return ids[id];
}
public void union(int id1, int id2) {
int root1 = root(id1), root2 = root(id2);
if (root1 == root2) return; //一定要检查,没查就错了
if (weights[root1] >= weights[root2]) {
ids[root2] = root1;
weights[root1] += weights[root2];
crowns[root1] += crowns[root2];
} else {
ids[root1] = root2;
weights[root2] += weights[root1];
crowns[root2] += crowns[root1];
}
}
public int getWeight(int id) {
return weights[id];
}
public int getCrown(int id) {
return crowns[id];
}
}