前言
本博文部分图片, 思路来自于剑指offer 或者编程珠玑
问题描述
示例
思路
对于这个问题, 书上给出的解法是给定一个索引表示当前打印的第几圈, 然后一圈一圈的打印
书中的思路 我会在下面贴出来
而下面的参考代码是我的思路, 这道题似乎 我在两年前就见过了吧, 而解答的思路就是那个时候的思路
代码中还有一个方法是生成蛇形矩阵, 思路和上面蛇形打印矩阵的思路一致
思路如下 :
书中的思路
参考代码
/**
* file name : Test05ClockwisePrintMatrix.java
* created at : 10:08:32 AM Jun 7, 2015
* created by 970655147
*/
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;
}
}
效果截图
总结
这个题目很常见, 也不是很难, 但是 我的思路的代码似乎看着有些冗杂
注 : 因为作者的水平有限,必然可能出现一些bug, 所以请大家指出!