54螺旋矩阵

螺旋矩阵

题目描述:给定一个包含 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值