螺旋矩阵
题目描述:给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
示例 1:
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]
示例 2:
输入:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]
解题思路:分层次遍历,由外及内,定义四个方向操作,注意边界操作,这一题需要多做几遍,完全理解。按照下图遍历。
- 对于每层,我们从左上方开始以顺时针的顺序遍历所有元素,假设当前层左上角坐标是 {(r1, c1)}(r1, c1),右下角坐标是{(r2, c2)}(r2, c2)。
- 首先,遍历上方的所有元素 {(r1, c)}(r1, c),按照{c = c1,…,c2}c = c1,…,c2 的顺序。然后遍历右侧的所有元素 {(r, c2)}(r, c2),按照 {r = r1+1,…,r2}r = r1+1,…,r2 的顺序。如果这一层有四条边(也就是 {r1 < r2}r1 < r2 并且{c1 < c2}c1 < c2 ),我们以下图所示的方式遍历下方的元素和左侧的元素。
int* spiralOrder(int** matrix, int matrixSize, int* matrixColSize, int* returnSize){
int r,c,r1,r2,c1,c2,count;
if(!matrixSize||!matrixColSize[0]){
*returnSize=0;
return NULL;
}
int *result=(int *)malloc(sizeof(int)*matrixSize*matrixColSize[0]);
*returnSize=matrixSize*matrixColSize[0];
r1=c1=count=0;
r2=matrixSize-1;
c2=matrixColSize[0]-1;
while(r1<=r2&&c1<=c2){
for(c=c1;c<=c2;c++)result[count++]=matrix[r1][c];
for(r=r1+1;r<=r2;r++)result[count++]=matrix[r][c2];
if(r1<r2&&c1<c2){
for(c=c2-1;c>c1;c--)result[count++]=matrix[r2][c];
for(r=r2;r>r1;r--)result[count++]=matrix[r][c1];
}
r1++;
r2--;
c1++;
c2--;
}
return result;
}
法二:假设数组有 R 行 C 列,{seen[r][c]}seen[r][c] 表示第 r 行第 c 列的单元格之前已经被访问过了。当前所在位置为 (r, c),前进方向是di。我们希望访问所有R x C 个单元格。
当我们遍历整个矩阵,下一步候选移动位置是(cr, cc)。如果这个候选位置在矩阵范围内并且没有被访问过,那么它将会变成下一步移动的位置;否则,我们将前进方向顺时针旋转之后再计算下一步的移动位置。
int* spiralOrder(int** matrix, int matrixSize, int* matrixColSize, int* returnSize){
if(!matrixSize||!matrixColSize[0]||!matrix){
*returnSize=0;
return NULL;
}
int r,c,rr,cc,di,seen[matrixSize][matrixColSize[0]];
int dr[4]={0,1,0,-1};
int dc[4]={1,0,-1,0};
memset(seen, 0, sizeof(seen));
int res_size=matrixSize*matrixColSize[0];
int *result=(int *)malloc(sizeof(int)*res_size);
*returnSize=res_size;
r=c=di=0;
for(int i=0;i<res_size;i++){
result[i]=matrix[r][c];
seen[r][c]=1;
cc=c+dc[di];
rr=r+dr[di];
if(0<=cc&&cc<matrixColSize[0]&&0<=rr&&rr<matrixSize&&!seen[rr][cc]){
c=cc;
r=rr;
}
else{
di=(di+1)%4;
c=c+dc[di];
r=r+dr[di];
}
}
return result;
}