Java矩阵运行时错误

时间:2016-04-18 23:44:23

标签: java matrix spiral

练习信:

给定m×n个元素的矩阵(m行,n列),以螺旋顺序返回矩阵的所有元素。

例如,给定以下矩阵:

private void ListenForIncomingHttpRequests()
{
    AwaitNetworkAvailability();

    // create
    var serverSocket = 
        new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    // bind
    var localEndpoint = new IPEndPoint(IPAddress.Any, port: 12000);
    serverSocket.Bind(localEndpoint);

    // listen
    serverSocket.Listen(backlog: 25);

    while (true)
    {
        AwaitNetworkAvailability();

        try
        {
            // client connects to the server
            using (var clientSocket = serverSocket.Accept())
            {
                ProcessServerSocketRequest(clientSocket);
            }
        }
        catch (Exception ex)
        {
            _logger.Write(ex.ToString());
        }
    }
}

代码:

[
     [ 1, 2, 3 ],
     [ 4, 5, 6 ],
     [ 7, 8, 9 ]
    ]
    You should return [1,2,3,6,9,8,7,4,5].

我的代码:

public class Solution {
  public List<Integer> spiralOrder(int[][] matrix) {
  }
}

错误:

public List<Integer> spiralOrder(int[][] matrix) {
        if(matrix == null || (matrix.length == 0))
            return new ArrayList<Integer>();
        int arriba = 0;
        int derecha = matrix[0].length - 1;
        int abajo = matrix.length - 1;
        int izquierda = 0;
        List<Integer> retorno = new ArrayList<Integer>();
        while(true)
        {
            for(int i = izquierda; i <= derecha; i++)
                retorno.add(matrix[arriba][i]);
            arriba++;
            for(int i = arriba; i <= abajo; i++)
                 retorno.add(matrix[i][derecha]);
            derecha--;
            for(int i = derecha; i >= izquierda; i--)
                retorno.add(matrix[abajo][i]);
            abajo--;
            for(int i = abajo; i >= arriba; i--)
                retorno.add(matrix[i][izquierda]);
            izquierda++;
            if(izquierda >= derecha)
                return retorno;
        }
    }
}

有什么建议吗?我无法确切地说出错了什么。为什么它超出范围? 可以找到练习here

2 个答案:

答案 0 :(得分:1)

试试这个。

static int[][] DIRECTIONS = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};

static boolean movable(int r, int c, int height, int width, boolean[][] visited) {
    if (r < 0 || r >= height || c < 0 || c >= width)
        return false;
    return !visited[r][c];
}

public List<Integer> spiralOrder(int[][] matrix) {
    List<Integer> result = new ArrayList<>();
    int height = matrix.length;
    if (height == 0) return result;
    int width = matrix[0].length;
    if (width == 0) return result;
    boolean[][] visited = new boolean[height][width];
    int direction = 0;
    int r = 0, c = 0;
    for (int i = 0; i < width * height; ++i) {
        result.add(matrix[r][c]);
        visited[r][c] = true;
        int[] directions = DIRECTIONS[direction % DIRECTIONS.length];
        if (!movable(r + directions[0], c + directions[1], height, width, visited))
            directions = DIRECTIONS[++direction % DIRECTIONS.length];
        r += directions[0];
        c += directions[1];
    }
    return result;
}

答案 1 :(得分:1)

我用这个矩阵尝试了你的方法:

int[][] matrix = {{1,2,3},
                  {2,3,4},
                  {3,4,5}};

我没有得到任何ArrayIndexOutOfBoundsException。您的代码似乎没有任何错误。

但是,我注意到输出不符合预期。它给我的输出是12345432(只有8个数字),缺少矩阵中间的数字3

仔细查看代码后,我意识到错误在于if(izquierda >= derecha)。如果将其更改为if(izquierda > derecha),则不会错过3。出于同样的原因,您还需要检查arriba > abajo,否则您的程序不适用于列数多于行数的矩阵。

编辑:每次for循环后都需要进行这些检查。

我建议你将return retorno;移到while循环之外,然后在支票中插入break

public List<Integer> spiralOrder(int[][] matrix) {
    if(matrix == null || (matrix.length == 0))
        return new ArrayList<Integer>();
    int arriba = 0;
    int derecha = matrix[0].length - 1;
    int abajo = matrix.length - 1;
    int izquierda = 0;
    List<Integer> retorno = new ArrayList<Integer>();
    while(true)
    {
        for(int i = izquierda; i <= derecha; i++)
            retorno.add(matrix[arriba][i]);
        arriba++;
        if(arriba > abajo)
            break;

        for(int i = arriba; i <= abajo; i++)
             retorno.add(matrix[i][derecha]);
        derecha--;
        if(izquierda > derecha)
            break;

        for(int i = derecha; i >= izquierda; i--)
            retorno.add(matrix[abajo][i]);
        abajo--;
        if(arriba > abajo)
            break;

        for(int i = abajo; i >= arriba; i--)
            retorno.add(matrix[i][izquierda]);
        izquierda++;
        if(izquierda > derecha)
            break;
    }
    return retorno;
}

您的代码说明(按要求):想象一下,您有一个矩阵,周围有四个人 - 每个人都站在一边。这四个人被称为arribaderechaabajoizquierda

           arriba
          1 2 3 4 5
izquierda 2 3 4 5 6 derecha
          3 4 5 6 7
            abajo

这四个人可以在他们面前看到数字线:

  • arriba看到1 2 3 4 5
  • derecha看到5 6 7
  • abajo看到3 4 5 6 7
  • izquierda看到1 2 3

每当这些人面前的所有数字都被添加到列表retorno中时,他们就会向前跳一步。例如,在第一个for循环之后,它看起来像这样:

          1 2 3 4 5
           arriba
izquierda 2 3 4 5 6 derecha
          3 4 5 6 7
            abajo

在while循环的第一次迭代之后,它们就像这样:

1           2 3 4         5
           arriba
2 izquierda 3 4 5 derecha 6
            abajo
3           4 5 6         7
  • arriba正在向下移动。
  • derecha向左移动。
  • abajo正在向上移动。
  • izquierda正在向右移动。

一旦这两个人中的任何相互通过,你知道它们之间没有数字,你需要立即停止循环 。这就是为什么你需要检查是否有两个人每次有人采取了一个步骤(在每个for循环之后)。