leetcode矩阵类题目专杀之54. Spiral Matrix

来源:互联网 发布:xd查询软件 编辑:程序博客网 时间:2024/06/05 19:20

这道题提交了4遍才通过,思路不算难,但边界条件要想清楚,还要注意矩阵中行和列的坑。简单来说,维护一个变量currentPosition从【0,0】开始,加入结果数组后,再进行nextPosition()计算,获取spiral规则下的下一个位置,当下一个位置已不存在时,currentPosition用null标记,结束循环迭代,返回结果。

那么如何计算nextPosition呢?原则有两个,一个是确定下一步当方向,当列数为1的时候,初始方向为向下,否则初始方向为向右,为了简单,用1表示向右,2表示向下,3表示向左,4表示向上,那么更新方向的顺序一定是1-2-3-4-1-2-3-4....这个样子,每次发现在改方向无路可走的时候按照这个规则更新方向即可。那么如何判断无路可走呢?要么已经抵达数组边界,要么下一个位置已经访问过,如何标记已经访问过呢?为了省空间,最好的方式当然是用BitSet了,否则另外开辟一个同等大小的空间有点浪费。


还要注意一个边界条件是输入为空的情况:[[]]。


另外就是要注意设置bitSet时,应该用i*column+j,而不是i*row+j,尼玛第一次搞错了,这是个坑。


上代码:

public class Solution {// sample input: /* * [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ]] * *///sample output: 1,2,3,6,9,8,7,4,5private int direction = 1;public void nextDirection(){if(this.direction<4){this.direction += 1;}else{this.direction = 1;}}private class Position{public int i;public int j;}public boolean visited(BitSet bs, int column, int i, int j){return bs.get(column*i+j);}public Position nextPosition(Position currentPosition,  BitSet bs, int row, int column){switch(direction){case 1:// if next availableif(currentPosition.j<column-1 && !visited(bs, column, currentPosition.i, currentPosition.j+1)){// move rightcurrentPosition.j=currentPosition.j+1;// check again, if next not availble, change directionif(!(currentPosition.j<column-1 && !visited(bs, column, currentPosition.i, currentPosition.j+1))){this.nextDirection();}return currentPosition;}else{return null;}case 2:// move down// if next availableif(currentPosition.i<row-1 && !visited(bs, column, currentPosition.i+1, currentPosition.j)){currentPosition.i=currentPosition.i+1;if(!(currentPosition.i<row-1 && !visited(bs, column, currentPosition.i+1, currentPosition.j))){this.nextDirection();}return currentPosition;}else{return null;}case 3://move leftif(currentPosition.j>0 && !visited(bs, column, currentPosition.i, currentPosition.j-1)){currentPosition.j=currentPosition.j-1;if(!(currentPosition.j>0 && !visited(bs, column, currentPosition.i, currentPosition.j-1))){this.nextDirection();}return currentPosition;}else{return null;}case 4://move upif(currentPosition.i>0 && !visited(bs, column, currentPosition.i-1, currentPosition.j)){currentPosition.i=currentPosition.i-1;if(!(currentPosition.i>0 && !visited(bs, column, currentPosition.i-1, currentPosition.j))){this.nextDirection();}return currentPosition;}else{return null;}default:return null;}}    public List<Integer> spiralOrder(int[][] matrix) {    List<Integer> result = new ArrayList();    // 1: right, 2:down, 3:left, 4:up    int row = matrix.length;    if(row==0){    return result;    }    int column = matrix[0].length;        if(column<=1){    this.nextDirection();    }        Position currentPosition = new Position();    currentPosition.i=0;    currentPosition.j=0;    BitSet bs = new BitSet();    while(currentPosition != null){    result.add(matrix[currentPosition.i][currentPosition.j]);    bs.set(currentPosition.i*column+currentPosition.j);    currentPosition = nextPosition(currentPosition, bs, row, column);    }                return result;    }}


原创粉丝点击