前言

本博文部分图片, 思路来自于剑指offer 或者编程珠玑

问题描述

12 蛇形打印矩阵中的数据_蛇形矩阵

示例

12 蛇形打印矩阵中的数据_i++_02

思路

对于这个问题, 书上给出的解法是给定一个索引表示当前打印的第几圈, 然后一圈一圈的打印

12 蛇形打印矩阵中的数据_算法_03


书中的思路 我会在下面贴出来

而下面的参考代码是我的思路, 这道题似乎 我在两年前就见过了吧, 而解答的思路就是那个时候的思路
代码中还有一个方法是生成蛇形矩阵, 思路和上面蛇形打印矩阵的思路一致

思路如下 :

12 蛇形打印矩阵中的数据_算法_04


书中的思路

12 蛇形打印矩阵中的数据_java_05

12 蛇形打印矩阵中的数据_蛇形矩阵_06

参考代码

/**
 * file name : Test05ClockwisePrintMatrix.java
 * created at : 10:08:32 AM Jun 7, 2015
 * created by
 */

package com.hx.test05;

import com.hx.util.Log;

public class Test05ClockwisePrintMatrix {

    // 打印蛇形矩阵, 顺时针打印int[][]
    public static void main(String[] args) {

        int width = 3, height = 4;
        int[][] arr = generateTwoDimenArr(width, height);
        Log.logWithoutPosition(arr);

        clockwisePrintMatrix(arr);

        // ----------------------
        generateSnakeMatrix(arr);
        Log.enter();
        Log.horizon();
        Log.logWithoutPosition(arr);

    }

    // 打印蛇形矩阵
    // 思路 : 打印(0, 0) -> (width, 0)   需要打印width-diff个数字, diff随着循环而变化
            // 打印(width, 0) -> (width, height)  需要打印height-diff-1个数字
            // 打印(width, height) -> (0, height)  需要打印width-diff-1个数字
            // 打印(0, height) -> (0, 1)           需要打印height-diff-2个数字
        // 每一次循环diff + 1, 本程序 这里就直接在第一次打印 和第三次打印 将diff更新了
    // 请注意  更新row, col的方式     如果你不理解的话   请画一个矩阵  试着走一下, 可以帮你理解这个逻辑
    public static void clockwisePrintMatrix(int[][] arr) {
        int diff = 0;
        int rowNum = arr.length, colNum = arr[0].length;
        int printed = 0, eleNum = arr.length * arr[0].length;
        int row = 0, col = 0;

        while(true) {
            // (0, 0) -> (width, 0)
            for(int i=0; i<colNum-diff; i++) {
                Log.logWithoutLn(arr[row][col ++] + " ");
            }
            col --; row ++;
            printed += (colNum - diff);
            diff ++;
            if(printed >= eleNum) {
                break ;
            }

            // (width, 1) -> (width, height)
            for(int i=0; i<rowNum-diff; i++) {
                Log.logWithoutLn(arr[row ++][col] + " ");
            }
            row --; col --;
            printed += (rowNum-diff);
            if(printed >= eleNum) {
                break ;
            }

            // (width-1, height) -> (0, height)
            for(int i=0; i<colNum-diff; i++) {
                Log.logWithoutLn(arr[row][col --] + " ");
            }
            col ++; row--;
            printed += (colNum - diff );
            if(printed >= eleNum) {
                break ;
            }
            diff ++;

            // (0, height-1) -> (0, 1)
            for(int i=0; i<rowNum-diff; i++) {
                Log.logWithoutLn(arr[row --][col] + " ");
            }
            row ++; col++;
            printed += (rowNum - diff);
            if(printed >= eleNum) {
                break ;
            }
        }

    }

    // 创建蛇形矩阵
    // 思路 : 打印(0, 0) -> (width, 0)   需要打印width-diff个数字, diff随着循环而变化
            // 打印(width, 0) -> (width, height)  需要打印height-diff-1个数字
            // 打印(width, height) -> (0, height)  需要打印width-diff-1个数字
            // 打印(0, height) -> (0, 1)           需要打印height-diff-2个数字
        // 每一次循环diff + 1, 本程序 这里就直接在第一次打印 和第三次打印 将diff更新了
    // 请注意  更新row, col的方式     如果你不理解的话   请画一个矩阵  试着走一下, 可以帮你理解这个逻辑
    public static void generateSnakeMatrix(int[][] arr) {
        int diff = 0;
        int rowNum = arr.length, colNum = arr[0].length;
        int printed = 0, eleNum = arr.length * arr[0].length;
        int row = 0, col = 0;
        int cur = 0;

        while(true) {
            // (0, 0) -> (width, 0)
            for(int i=0; i<colNum-diff; i++) {
                arr[row][col ++] = (cur ++);
            }
            col --; row ++;
            printed += (colNum - diff);
            if(printed >= eleNum) {
                break ;
            }
            diff ++;

            // (width, 1) -> (width, height)
            for(int i=0; i<rowNum-diff; i++) {
                arr[row ++][col] = (cur ++);
            }
            row --; col --;
            printed += (rowNum-diff);
            if(printed >= eleNum) {
                break ;
            }

            // (width-1, height) -> (0, height)
            for(int i=0; i<colNum-diff; i++) {
                arr[row][col --] = (cur ++);
            }
            col ++; row--;
            printed += (colNum - diff );
            if(printed >= eleNum) {
                break ;
            }
            diff ++;

            // (0, height-1) -> (0, 1)
            for(int i=0; i<rowNum-diff; i++) {
                arr[row --][col] = (cur ++);
            }
            row ++; col++;
            printed += (rowNum - diff);
            if(printed >= eleNum) {
                break ;
            }
        }

    }

    // 生成一个height个元素的, 每一个元素width个int的int[][]
    private static int[][] generateTwoDimenArr(int width, int height) {
        int[][] res = new int[height][width];
        int cnt = 0;
        for(int row=0; row<height; row++) {
            for(int col=0; col<width; col++) {
                res[row][col] = cnt++;
            }
        }

        return res;
    }

}

效果截图

12 蛇形打印矩阵中的数据_算法_07

总结

这个题目很常见, 也不是很难, 但是 我的思路的代码似乎看着有些冗杂

注 : 因为作者的水平有限,必然可能出现一些bug, 所以请大家指出!