确定网格中的分组值的数量

时间:2014-12-05 20:41:28

标签: java grid logic grouping cell

想知道是否有人能用某种逻辑来帮助我。

假设我有一个由以下内容组成的网格:

  1 2 3
1 A B A
2 A B B
3 A A B

此网格中有3个组,由每个单元格的值和具有相同值的所有相邻单元格确定,因此假设坐标方案为(col,row):

第1组:(1,1),(1,2),(1,3),(2,3),其值为A

第2组:(2,1),(2,2),(3,2),(3,3),其值为B

第3组:(3,1),其值为A

有人可以建议我如何以编程方式确定?

我正在思考:

  • 使用for循环遍历网格
    • 有一种方法可以检查单元格的顶部,右侧,底部和左侧单元格的值(也考虑边界单元格)
      • 检查单元格是否具有相同的值,然后以某种方式存储
      • 否则它是一个新组?
    • 递归

但如果发现一个具有不同值的单元格,我无法解决该怎么做。我想我在这里复杂化一个简单的解决方案。

理想情况下,我希望存储一个与网格中所有组相关的坐标数组。

1 个答案:

答案 0 :(得分:0)

我认为概念上最简单的处理方法是使用递归。当然,由于Java的低级尾递归支持,迭代解决方案会更有效率;仍然,递归应该适用于小的值。

看看这个示例代码

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<>();
    }
}

我们逐步完成网格,尝试将每个条目用作&#34; root&#34;一个新的团体。如果一个不同的组实际上以该条目为根(即grpCt!= 0),那么我们打印它。

在getGroupMethod中,我们首先检查我们是否已超出网格范围,或者我们是否已经使用过前一组中的条目。请注意,此检查是通过改变网格来完成的,但我们可以保留备忘录。

否则,如果当前条目与我们正在寻找分组的状态相匹配,那么我们将此条目添加到该组,然后向所有方向展开,寻找要添加到该组的其他条目。

否则,我们知道目前的条目不能成为该组的一部分。

编辑:就渐近运行时而言,因为我们通过在网格中设置标志来有效地进行记忆,因此只考虑每个条目最多4次,我们得到了O(n ^ 2)