54-螺旋矩阵(技巧,四个点标记矩阵边界)
思路:等于是说,让我们顺时针一圈一圈的遍历一个矩阵,结果放在一个List里面。
1.因为是一圈一圈遍历,可以用四个点标记当前这个矩阵的四个角,然后按照行列行列的次序,把每个点加入结果结合里面。有四个点:c1,c2,r1,r2,分别是最左边的列的下标,最右边的列的下标,最上面行的下标,最下面行的下标。
2.要注意,只有一行或者一列的时候比较特殊,这时候,不需要按照“行列行列”遍历。只有一行时,直接遍历这一行全部。只有一列时,第一次遍历一个元素,也就是第一行。之后遍历剩下的元素,也就是第一列。(遍历完第一个“行列”时,判断一下是否有必要遍历第二个“行列”)
3.根据第二条,“行列行列”这个顺序里,第一个“行”,应该是遍历这一行所有元素;第一个“列”,应该是遍历c2列里面,r1+1这一行,到r2的所有元素。
class Solution { public List<Integer> spiralOrder(int[][] matrix) {//重点是边界的处理和只有一行的情况 List ans=new ArrayList(); if (matrix.length == 0) return ans; //下面用四个点,标记当前这个矩阵的四个角。因为按照顺时针顺序输出的,所以最外层循环过后,就该内层了,每遍历一层,矩阵就会少一圈 int r1=0;//行坐标1 int r2=matrix.length-1;//行坐标2 int c1=0;//列坐标1 int c2=matrix[0].length-1;//列坐标2 while(r1<=r2&&c1<=c2)//当这种情况下螺旋遍历 { //矩阵第一行 for(int i=c1;i<=c2;i++) ans.add(matrix[r1][i]);//必须这样,小于等于c2,不然,假如三行三列,最中间的数遍历不到,因为第一圈遍历完,c1,c2,r1,r2都等于1了,假如不写成<=,永远遍历不到 //最右边的列 for(int i=r1+1;i<=r2;i++) ans.add(matrix[i][c2]); if(r1<r2&&c1<c2) { //最下边的行,注意是倒叙 for(int i=c2-1;i>c1;i--)ans.add(matrix[r2][i]); //最左边那一行,也是从下往上遍历的 for(int i=r2;i>r1;i--)ans.add(matrix[i][c1]); } r1++; r2--; c1++; c2--; } return ans; } }