剑指offer--顺时针打印矩阵

顺时针打印矩阵 题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。 (注意:矩阵可以是3*3,4*2,6*1)

这里写图片描述

分析:

  1. 从矩阵[0][0]开始遍历。
  2. 先遍历到矩阵某个方向上的末端。
  3. 换下个方向。如果没有可以遍历的位置,结束遍历。
  4. 如果有可以遍历的位置,继续第2步。

问题的关键:
  如何判断某个位置是否被遍历过?
   创建一个与矩阵同等大小的标记矩阵,每经过一个点,便标记一次。
   
  如何判断某个方向上是否还有格子打印?
   试生成next_point,对这个点进行界限判断和标记判断。
   
  如何判断下个方向上还有格子能打印?
   采用一个投机的办法就是,计算总共需要的遍历的点的个数,每次遍历维护一个当前已经遍历节点的个数,若未达到总个数,则说明下个方向上还有格子未打印。

public class 面试题29 {
    public static void main(String[] args) {
        int[][] matirx1 = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };
        print(matirx1);

        int[][] matirx2 = { { 1 } };
        print(matirx2);

        int[][] matirx3 = { {1,2,3,4,5,6} };
        print(matirx3);
    }

    public final static int[][] dir = { { 0, 1 }, { 1, 0 }, { -1, 0 }, { 0, -1 } };// 右,下,左,上

    public static void print(int[][] matirx) {
        if (matirx == null) // 如果矩阵为空
            return;
        boolean[][] mat = new boolean[matirx.length][matirx[0].length];
        int count = (matirx.length) * (matirx[0].length);// 总个数
        int sum = 0;// 当前遍历个数
        int dirction = 0;// 当前方向
        int[] point = { 0, 0 };// 当前位置
        int[] next_point = new int[2];// 下个位置

        System.out.print(matirx[0][0] + " ");
        mat[0][0] = true;
        sum++;
        while (true) {
            // 单方向遍历
            while (true) {
                next_point[0] = point[0] + dir[dirction % 4][0];
                next_point[1] = point[1] + dir[dirction % 4][1];

                if (next_point[0] < 0 || next_point[0] >= matirx.length || next_point[1] < 0
                        || next_point[1] >= matirx[0].length) {
                    break;
                }

                if (mat[next_point[0]][next_point[1]]) {
                    break;
                }
                point[0] = next_point[0];
                point[1] = next_point[1];
                System.out.print(matirx[point[0]][point[1]] + " ");
                mat[point[0]][point[1]] = true;
                sum++;
            }
            if (sum >= count)
                break;
            dirction++;
        }
        System.out.println();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值