打印蛇形矩阵

2,444 阅读2分钟

具体的题目名字忘记了,之前记得有个算法题目,根据给出的整数打印有规律的矩阵。

当n=3:

1	2	3
8	9	4
7	6	5

当n=4:

1	2	3	4
12	13	14	5
11	16	15	6
10	9	8	7

可以看出来规律比较明显,那么自己尝试解一下这个题目

首先根据题意,画出规律图,可以得出规律:

  • 走完4圈为一个循环,后续步骤与之前的步骤是一样的

  • 程序最大的数为 n * n

image-20190325171645162

限定程序的边界条件

编码

  1. 在限定条件内进行操作
		while (count <= n * n) {
			//.. 依次填充数据
        }
  1. 填充数据,根据上面分析图的条件
        while (count <= n * n) {
            int x = offset;
            int y = offset;
            // 首先x=0,y++ && y<n
            for (; y < n - offset; y++) {
                System.out.println("First 设置点位信息:[" + x + "," + y + "]" + ",count=" + count);
                res[x][y] = count;
                count++;
            }

            // 然后y=n-1, x++ && x <n
            x++;
            for (; x < n - offset; x++) {
                System.out.println("Second 设置点位信息:[" + x + "," + (y - 1) + "]" + ",count=" + count);
                res[x][y - 1] = count;
                count++;
            }

            // 然后x=n,y-- && y>=0
            y--;
            for (; y > offset; y--) {
                System.out.println("Third 设置点位信息:[" + (x - 1) + "," + (y - 1) + "]" + ",count=" + count);
                res[x - 1][y - 1] = count;
                count++;
            }

            // 最后y=0 && x-- && x > offset+1
            x--;
            for (; x > offset + 1; x--) {
                System.out.println("Fourth 设置点位信息:[" + (x - 1) + "," + y + "]" + ",count=" + count);
                res[x - 1][y] = count;
                count++;
            }
            offset++;
        }
    }
  1. 运行一下,看看效果,打印信息,为了方便调试,看看是否按照自己的预期填充点位。

image-20190325172351959

额外

据说还有输出这样的矩阵:

1 2 6 7
3 5 8 13
4 9 12 14
10 11 15 16

x +y = 0, [0,0] => 1
x +y = 1, [0,1]=>2, [1,0] => 3 x +y = 2, [2,0]=>4,[1,1] => 5 , [0,2]=>6
x +y = 3, [0,3]=>7,[1,2] => 8 , [2,1]=>9 , [3,0]=>10 x +y = 4, [3,1]=>11,[2,2] => 12 , [1,3]=>13 x +y = 5, [2,3]=>14,[3,2] => 15 x + y = 6, [3,3] = 16

注意:

  • (x+y) % 2 = 0, x--,y++ && (x + y) = sum
  • (x + y) % 2 = 1,x++,y-- && (x + y) = sum
  • 0 <= sum <= 2 * (n-1)
  • 去除一些超过边界的点
    static void printSnake(int n){
        int[][] res = new int[n][n];
        int count = 1;
        int sum = 0;

        int x = 0;
        int y = 0;
        while (sum <= 2 * (n-1)){
            // 设置向上递增的
            if (sum % 2 == 0){                
                while (x >= n){
                    x--;
                    y++;
                }
                for (;(x + y) == sum && x>=0 && y < n;x--,y++){
                    System.out.println(
                            String.format("[x,y]=[%d,%d]=%d",x,y,count)
                    );
                    res[x][y] = count;
                    count++;
                }
                x++;
            // 设置向下递增的   
            }else {
                while (y >= n){
                    x++;
                    y--;
                }
                for (;(x + y) == sum && y>=0 && x < n;x++,y--){
                    System.out.println(
                            String.format("[x,y]=[%d,%d]=%d",x,y,count)
                    );
                    res[x][y] = count;
                    count++;
                }
                y++;
            }
            sum++;
        }

        for (int i = 0; i < res.length; i++) {
            for (int j = 0; j < res[i].length; j++) {
                System.out.print(res[i][j]);
                System.out.print(",");
            }
            System.out.println("");
        }

    }

测试结果:

image-20190325175116060

符合预期

最后

思路清晰,才能写出正确的代码