Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
Example 1:
Input:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
Output: [1,2,3,6,9,8,7,4,5]
给一个二维数组,要求按照漩涡的顺序输出数组中的元素
漩涡的顺序就是从[0][0]开始往右,碰到右边界往下,转圈直到输出所有元素
思路:
就上面的例子,这里用i代表行,j代表列
漩涡的顺序:i=0,j=0,1,2, j到右边界,这时j不变,i++
j=2,i=1,2,i到下边界,这时i不变,j–
i=2,j=1,0,j到左边界,这时j不变,i–
j=0,i=1, i到上边界,j++
所以rule有四条:
- i=上边界时, j++,行的上边界++(只执行一次)
- j=右边界时,i++,列的右边界–(只执行一次)
- i=下边界时,j–,行的下边界–(只执行一次)
- j=左边界时,i–,列的左边界++(只执行一次)
简化为:
(1 ) i上边界时,
{ j从左到右loop,loop完后表示最上面一行的元素已经输出完,所以i的上边界++
j到最右边时,i从上到下loop,loop完表示最右边一列已经输出完,j的右边界–
}
(2) i下边界时
{ j从右到左loop,loop完后表示最后一行已经输出完,所以行的下边界–
j到最左边时,i从下到上loop,loop完表示最左边一列已经输出完,左边界++
}
(3) 直到上边界<=下边界 和 左边界 <= 右边界的条件不再成立
因为一次循环要处理(1)(2)两种情况,而处理完(1)后可能(3)不再满足,但是(3)只在循环完一次的时候才做判断,所以(2)的条件中还要加入(3)的判断
public List<Integer> spiralOrder(int[][] matrix) {
int rows = matrix.length;
int cols = matrix[0].length;
int r = 0;
int c = 0;
int minR = 0;
int maxR = rows-1;
int minC = 0;
int maxC = cols-1;
List<Integer> res = new ArrayList<>();
while(minR <= maxR && minC <= maxC) {
if(minR <= maxR && minC <= maxC && r == minR) {
while(c <= maxC) {
res.add(matrix[r][c]);
c++;
}
//最后一个c++导致c = maxC+1
c = maxC;
minR ++;
r = minR; //r更新到新的minR,不写会出现重复数字
while(r <= maxR) {
res.add(matrix[r][c]);
r++;
}
r = maxR; //最后一个r++导致r=maxR+1
maxC--;
c = maxC; //c要更新到新的maxC上,不写这一步会出现重复数字
}
if(minR <= maxR && minC <= maxC && r == maxR) {
while(c >= minC) {
res.add(matrix[r][c]);
c --;
}
c = minC;
maxR--;
r = maxR; //r更新到新的maxR,不写会出现重复数字
while(r >= minR) {
res.add(matrix[r][c]);
r --;
}
r = minR; //最后一个r--导致r=minR-1
minC++;
c = minC; //c要更新到新的minC上,不写这一步会出现重复数字
}
}
return res;
}