二维数组回形遍历

GitHub跳转原题关系图返回列表

维护上下左右四条边界,按上右下左顺序逐层输出矩阵元素。

OJ: noi_openjudge

题目 ID: ch0108-23

难度:入门

标签:矩阵模拟遍历python

日期: 2026-07-30 23:01

题意

从左上角开始顺时针向内回形遍历矩阵。

思路

维护未遍历区域的 topbottomleftright。依次走上边、右边、下边、左边,再整体收缩四条边界;单行或单列时跳过会重复输出的边。

代码

cpp
#include <cstdio>
int n,m,a[1010][1010];
void init(){
    scanf("%d%d",&n,&m);
    int i,j;
    for (i=1;i<=n;i++){
        for (j=1;j<=m;j++){
            scanf("%d",&a[i][j]);
        }
    }
}

int main(){
    init();
    int i,j;
    int r1=1,r2=n,c1=1,c2=m;
    while( r1 <= r2 && c1 <= c2){

        for(j=c1;j<=c2;j++)
            printf("%d\n",a[r1][j]);

        for(i=r1+1;i<=r2;i++)
            printf("%d\n",a[i][c2]);

        if( r1 != r2)
            for(j = c2-1;j>=c1;j--)
                printf("%d\n",a[r2][j]);

        if(c1!=c2)
            for(int i=r2-1;i>r1;i--)
                printf("%d\n",a[i][c1]);
        r1++;
        r2--;
        c1++;
        c2--;
    }
    return 0;
}

复杂度

总结

Python代码

python
row_count, column_count = map(int, input().split())
matrix = [list(map(int, input().split())) for _ in range(row_count)]
top, bottom = 0, row_count - 1
left, right = 0, column_count - 1

while top <= bottom and left <= right:
    for column in range(left, right + 1):
        print(matrix[top][column])
    for row in range(top + 1, bottom + 1):
        print(matrix[row][right])
    if top < bottom:
        for column in range(right - 1, left - 1, -1):
            print(matrix[bottom][column])
    if left < right:
        for row in range(bottom - 1, top, -1):
            print(matrix[row][left])
    top, bottom = top + 1, bottom - 1
    left, right = left + 1, right - 1

C++代码

cpp
#include <cstdio>
int n,m,a[1010][1010];
void init(){
    scanf("%d%d",&n,&m);
    int i,j;
    for (i=1;i<=n;i++){
        for (j=1;j<=m;j++){
            scanf("%d",&a[i][j]);
        }
    }
}

int main(){
    init();
    int i,j;
    int r1=1,r2=n,c1=1,c2=m;
    while( r1 <= r2 && c1 <= c2){

        for(j=c1;j<=c2;j++)
            printf("%d\n",a[r1][j]);

        for(i=r1+1;i<=r2;i++)
            printf("%d\n",a[i][c2]);

        if( r1 != r2)
            for(j = c2-1;j>=c1;j--)
                printf("%d\n",a[r2][j]);

        if(c1!=c2)
            for(int i=r2-1;i>r1;i--)
                printf("%d\n",a[i][c1]);
        r1++;
        r2--;
        c1++;
        c2--;
    }
    return 0;
}

复杂度

每个元素输出一次,时间复杂度为 O(rc)O(rc),矩阵空间为 O(rc)O(rc)

总结

螺旋遍历的关键是每圈结束后同步收缩四条边界。