【数据结构与算法】顺时针 循环打印 矩阵

本文深入探讨了矩阵元素的顺时针循环打印问题,提供了一种直观的思路和详细的代码实现,通过控制边界和遍历指针,实现了矩阵的螺旋形遍历。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

顺时针循环打印一个矩阵元素。
https://www.geeksforgeeks.org/print-a-given-matrix-in-spiral-form/

难点:如何控制下一步该往哪里走?

思路

想法一:如何控制下一步?下一步是由当前方向决定的。所以最直观的想法就是维护一个方向变量,然后建立一个偏移量的二维数组,第一维传入的方向,大小为4,第二维是x和y方向的前进量,大小为2。然后我们就根据方向来获取下一步移动的偏移量,如果碰壁,就修改方向,方向的修改是一个从大小为4的循环数组中轮流取值的过程。这个思路是可行的。当然还需要判定停止条件,可以用一个辅助数组记录哪些遍历过,如果遍历到一个已经遍历过的元素,就跳出,这是一种思路。

想法二:
想法一是可行的,但是其实可以省去方向变量和标记的过程,思考的模式变一下。
每一次x和y变化的坐标只有一个,所以我们只需要一个遍历指针(其实是变量);
整个过程可以看成是多轮遍历,每一轮包括四个方向,绕一圈;
也就是抽象为:
while(){
    for()
    for()
    for()
    for()
}

每一个内部的for,都会限定遍历的范围,遍历完就更新边界值。还要想好跳出的条件,就是遍历完一行或者一列,导致下一次没有空余的行或者列遍历了,也就是for之前判定一下行号或者列号的最大值是否小于最小值,如果是就break。那是不是每一个for循环都要判定?都判定肯定没问题,如果想要精简代码,只需要判定一个列的遍历和一个行的遍历即可。因为总会走到这个判定里。并且每一个for循环内部也不会受影响,因为for内部有条件限制。

代码

    public static void rotate(int[][] array) {
          //遍历指针
          int i;
          //边界
          int l = 0, k = 0, m = array.length - 1, n = array[0].length - 1;
          //主循环
          while (true) {
              //遍历上面的行
              for (i = k; i <= n; i++) {
                  System.out.println(array[l][i]);
              }
              //遍历完修改行的最小边界
              l ++;
              //遍历右侧的列
              for (i = l; i <= m; i++){
                  System.out.println(array[i][n]);
              }
              //遍历完修改列的右边界
              n --;
              
              //检测行是否遍历完了,如果碰上了,说明该退出
              if (l > m) {
                  break;
              }
              //遍历下面的行
              for (i = n; i >= k; i--) {
                System.out.println(array[m][i]);
              }
              //遍历完修改行的最大边界
              m--;
              //检测列是否遍历完了,如果碰上了,说明该退出
              if (k > n) {
                  break;
              }
              //遍历左侧的列
              for (i = m; i >= l; i--) {
                  System.out.println(array[i][k]);
              }
              //遍历完修改列的左边界
              k++;
          }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值