【剑指offer较难部分7】顺时针打印矩阵(java)

题目描述

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 × 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
在这里插入图片描述

分析

大致算法思路就是从左到右,从上到下,从右到左,从下到上遍历。
遍历方向共有4种,右,下,左,上。
当前遍历方向:1 表示 右,2 表示 下,3 表示 左,4 表示 上
dir为direction缩写
flagArr:定义一个二元数组记录对应位置是否已经走过

(1)向右移动到底,改变方向向下,行索引 row+1,列索引不变;
在这里插入图片描述

(2)向下移动到底,改变方向向左。行索引 row 不变,列索引 col-1
在这里插入图片描述

(3)向左移动到底,改变方向向上,行索引 row-1,列索引不变;
在这里插入图片描述

(4)向上移动到底,改变方向向右,行索引 row 不变,列索引 col+1
在这里插入图片描述
注:代码中为了与区分开始设置的总行数rows,总列数cols,中间行列变化用,i 与 j 表示

实现代码如下:

import java.util.*;
public class Solution {
     public ArrayList<Integer> printMatrix(int[][] matrix) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        if(matrix == null || matrix.length == 0){
            return list;
        }
        int rows = matrix.length;
        int cols = matrix[0].length;
        // 1.记录元素是否已经遍历过的数组 boolean[][] flagArr,默认值均为false;
        boolean[][] flagArr = new boolean[rows][cols];
        // 2.遍历索引,设置初始值
        int i = 0, j = -1;
        // 3.当前遍历方向:1:右,2:下,3:左,4:上
        int dir = 1;// 初始为向右
 
        // 开始遍历
        while (list.size() < rows * cols) {// 未遍历完
            // 根据当前方向判断前进方向,即按照目前方向判断当前元素是否可以打印,分为两个一个控制方向,一个进行添加到List
            if (dir == 1) {// 向右
                j++;
                if (j == cols || flagArr[i][j]) {// 向右超越边界或者当前元素已经遍历过
                    j--; // 回到前一个位置,下标表示最后一个应该是cols-1
                    dir = 2;// 方向变为向下
                }
            }
            if (dir == 2) {// 向下
                i++;
                if (i == rows || flagArr[i][j]) {
                    i--;
                    dir = 3;// 方向变为向左
                }
            }
            if (dir == 3) {// 向左
                j--;
                if (j < 0 || flagArr[i][j]) {//超过左边边界,或者当前元素已经遍历过
                    j++;
                    dir = 4;// 方向变为向上
                }
            }
            if (dir == 4) {// 向上
                i--;
                if (i < 0 || flagArr[i][j]) {
                    i++;
                    dir = 1;// 方向变为向右
                }
            }
            //没被遍历就添加
            if (!flagArr[i][j]){
                list.add(matrix[i][j]); //添加入list
            	flagArr[i][j] = true;//当前位置记为已经遍历过
           	}
        }
        return list;
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小样x

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值