我認爲處理這個概念上最簡單的方法是遞歸。當然,由於Java的subpar尾遞歸支持,迭代解決方案會更有效率;遞歸仍然適用於小的值。
看看此示例代碼
public static void main(String[] args) {
int xBound = 3;
int yBound = 3;
String[][] grid = new String[][] {
{"A", "B", "A"},
{"A", "B", "B"},
{"A", "A", "B"}
};
for(int i = 0; i < yBound; i++) {
for(int j = 0; j < xBound; j++) {
String state = grid[i][j];
List<List<Integer>> group = getGroup(state, j, i, xBound, yBound, grid);
if (group.size() != 0) {
System.out.println(state + " " + group);
}
}
}
}
static List<List<Integer>> getGroup(String state, int xIndex, int yIndex, int xBound, int yBound, String[][] grid) {
if (xIndex >= xBound || xIndex < 0 || yIndex >= yBound || yIndex < 0 || grid[yIndex][xIndex].equals("USED")) {
return new ArrayList<>();
} else if (grid[yIndex][xIndex].equals(state)){
grid[yIndex][xIndex] = "USED";
List<List<Integer>> ourPosse = new ArrayList<List<Integer>>();
ourPosse.add(Arrays.asList(yIndex, xIndex));
ourPosse.addAll(getGroup(state, xIndex + 1, yIndex, xBound, yBound, grid));
ourPosse.addAll(getGroup(state, xIndex - 1, yIndex, xBound, yBound, grid));
ourPosse.addAll(getGroup(state, xIndex, yIndex + 1, xBound, yBound, grid));
ourPosse.addAll(getGroup(state, xIndex, yIndex - 1, xBound, yBound, grid));
return ourPosse;
} else {
return new ArrayList<>();
}
}
我們通過網格步驟,欲以每個條目作爲新組的「根」。如果一個獨立的組實際上植根於該條目(即grpCt!= 0),那麼我們就打印它。
在getGroupMethod中,我們首先檢查我們是否已經離開了網格邊界,或者我們是否已經在前一個組中使用了條目。請注意,這種檢查是通過改變網格完成的,但我們可以保留備忘錄。否則,如果當前條目與我們希望分組的狀態相匹配,那麼我們將此條目添加到組中,然後向所有方向擴展,查找要添加到組的其他條目。
否則,我們知道當前條目不能成爲組的一部分。
編輯:就漸近運行時間而言,因爲我們通過在網格中設置標誌來有效地記憶,因此最多隻考慮每個條目4次,所以我們得到了O(n^2)。
第1組的值是不是ABAB? (1,1),(1,2),(1,3),(2,3)具有值A,B,A,B。你究竟想要做什麼? – RockOnRockOut 2014-12-05 20:52:23
對不起,如果我不清楚,座標方案是(col,row)。所以第一組是網格左邊的所有A和底部中間的一個。 我試圖首先確定網格中有多少個不同的組,然後獲取它所屬的每個單元的座標。希望這已經變得更加清晰 – willww 2014-12-05 21:09:52
好吧,我想我有點懂了。所以你想爲每個組提供一個座標數組? – RockOnRockOut 2014-12-05 21:12:42