如何在矩阵Java中找到2x3模式

hzbexzde  于 2023-01-29  发布在  Java
关注(0)|答案(2)|浏览(130)

这个算法把我难住了,我是个数据结构和算法的新手,我知道代码需要做什么,但是不能把我的大脑完全集中在如何实际编码上。
问题如下:
确定矩阵是否包含黄金票。黄金票由6个大写字母"G"组成,其中三对G位于彼此的正上方,如下所示。请注意,为了提高可读性,我省略了单引号。

G G
G G
G G

例如:
[阿、b、c、d、m]
[-G G ZG G-]
[H o-rG GD]此矩阵返回真
[高-rG GD]
例如:
[俄克-克日米西]
[-G GZG G-r]此矩阵返回false
[oG GG rG GD],因为G不在指定位置
[S t C-G Ga-]相对于彼此
矩阵应为"矩形",这意味着所有行都应具有相同数量的元素。如果不是这种情况,则应引发IllegalArgumentException。
这是我写的:

public static boolean goldenTicket(char[][] matrix) {
    if (matrix == null) return false;
    if (matrix.length == 0) return false;

    char char1, char2;
    int matchCount = 0;
    int indexOne = 0, indexTwo = 0, prevIndex1 = 0,prevIndex2 = 0;
    int rows = matrix.length;
    int columns = matrix[0].length;

    for (int i = 0; i < rows; i++) {
        if (matrix[i].length != columns)
            throw new IllegalArgumentException("Length of row doesn't match");
        if (matrix[i].length == 0) return false;
        if (matchCount == 3) return true;

        for (int j = 1; j < columns; j++) {
            if (matrix[i][j] == 'G' && matrix[i][j - 1] == 'G') {
                if (prevIndex1 == 0 && prevIndex2 == 0) {
                    indexOne = j - 1;
                    indexTwo = j;
                    matchCount++;
                } else {
                    prevIndex1 = j - 1;
                    prevIndex2 = j;
                    matchCount++;
                }
            }
        }

        if (prevIndex1 == indexOne && prevIndex2 == indexTwo) {
            matchCount++;
        }
    }
    return false;
}

然而,问题是代码通过了上面的示例一和示例二,而不是只通过了示例一。我已经提交了仅通过24/25测试的任务,我只是真的想了解这应该如何工作,也许是一个更好的编码方式,以供将来参考。
先谢了!

daupos2t

daupos2t1#

它可以用O(ncol*nrow)来求解,其中ncol是列数,nrow是行数。
您应该生成一个与原始矩阵具有相同行和列的矩阵,并且对于每一项,您考虑一对数字,其中第一个元素表示在行中包含该项的连续G的数量,第二个元素表示在列中包含该项的连续G的数量。
为了填充这个矩阵(我将其命名为onlyGMatrix),我们检查项(i,j)是否为G,如果不是,我们只需放入对(0,0),否则对于i>0 and j>0,我们将min {onlyGMatrix(i-1,j)[0] , onlyGMatrix(i,j-1)[0]} + 1作为第一个元素,将min {onlyGMatrix(i-1,j)[1] , onlyGMatrix(i,j-1)[1]} + 1作为第二个元素。
使用你的第一个矩阵,我们将得到下面的onlyGMatrix

(0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0)
(0,0) (0,0) (0,0) (0,0) (1,1) (2,1) (0,0)
(0,0) (0,0) (0,0) (0,0) (2,1) (2,2) (0,0)
(0,0) (0,0) (0,0) (0,0) (3,1) (3,2) (0,0)

对于第二个矩阵,我们将得到:

(0,0) (0,0) (1,1) (0,0) (0,0) (0,0) (0,0) (0,0)
(0,0) (1,1) (2,2) (0,0) (1,1) (2,1) (0,0) (0,0)
(0,0) (1,2) (2,3) (3,1) (0,0) (1,2) (2,1) (0,0)
(0,0) (0,0) (0,0) (0,0) (1,1) (2,1) (0,0) (0,0)

当你构建onlyGMatrix的时候,看到对(3,2)的时候,你的算法就成功结束了,如果你到达矩阵的最后一个元素,却没有看到这个对,那么你应该返回false.

yyyllmsg

yyyllmsg2#

对于这种类型的问题,分而治之可以帮助简化代码。
任务是在一个更大的矩阵中找到字母“G”的2 x 3矩阵。
因此,我们编写了一个方法来检查一个更大矩阵中的每个2 x 3矩阵。
这是我的一个测试结果。

[a, G, G, a]
[a, G, G, a]
[a, G, a, a]
[a, a, a, a]
false
[a, G, G, a]
[a, G, G, a]
[a, G, G, a]
[a, a, a, a]
true
[a, a, a, a]
[a, a, G, G]
[a, a, G, G]
[a, a, G, G]
true

我写了两个方法。
goldenTicket方法检查矩阵是否为空、是否小于2 x 3矩阵或列长度是否相同,最后一个代码块遍历矩阵以查找金票。
isTicket方法检查矩阵的当前2 x 3部分是否全部由“G”字母组成。
将代码分成两个方法使每个方法更小、更容易阅读,并在某种程度上隐藏了需要4个嵌套的for循环才能正确解决任务的事实。
下面是完整的可运行代码。

import java.lang.reflect.Array;
import java.util.Arrays;

public class GoldenTicketExample {

    public static void main(String[] args) {
        char[][] matrix1 = { { 'a', 'G', 'G', 'a' }, { 'a', 'G', 'G', 'a' },
                { 'a', 'G', 'a', 'a' }, { 'a', 'a', 'a', 'a' } };
        displayOutput(matrix1);
        char[][] matrix2 = { { 'a', 'G', 'G', 'a' }, { 'a', 'G', 'G', 'a' },
                { 'a', 'G', 'G', 'a' }, { 'a', 'a', 'a', 'a' } };
        displayOutput(matrix2);
        char[][] matrix3 = { { 'a', 'a', 'a', 'a' }, { 'a', 'a', 'G', 'G' },
                { 'a', 'a', 'G', 'G' }, { 'a', 'a', 'G', 'G' } };
        displayOutput(matrix3);
    }

    private static void displayOutput(char[][] matrix) {
        for (char[] row : matrix) {
            System.out.println(Arrays.toString(row));
        }
        System.out.println(goldenTicket(matrix));
    }

    public static boolean goldenTicket(char[][] matrix) {
        if (matrix == null) {
            return false;
        }
        if (matrix.length < 3) {
            return false;
        }

        int columns = matrix[0].length;
        if (columns < 2) {
            return false;
        }

        for (int row = 1; row < matrix.length; row++) {
            if (matrix[row].length != columns) {
                throw new IllegalArgumentException(
                        "Length of row doesn't match");
            }
        }

        for (int row = 0; row < matrix.length - 2; row++) {
            for (int column = 0; column < matrix[row].length - 1; column++) {
                if (isTicket(matrix, row, column)) {
                    return true;
                }
            }
        }

        return false;
    }

    private static boolean isTicket(char[][] matrix, int row, int column) {
        for (int r = row; r < row + 3; r++) {
            for (int c = column; c < column + 2; c++) {
                if (matrix[r][c] != 'G') {
                    return false;
                }
            }
        }

        return true;
    }

}

相关问题