スパイラル正方行列(列挙法、分割統治法、Javaバージョン、反時計回り)

コンテンツ

スパイラルマトリックスの概要

1.基礎が弱い学生に適した列挙方法

2.スパイラル正方行列コード


スパイラルマトリックスの概要

いわゆる「スパイラル正方行列」とは、任意のNについて、左上隅の最初のグリッドから時計回りのスパイラルの順序で1からN×Nまでの数値がN×N正方行列に入力されることを意味します。ここでは、反時計回りの例を次のように記述します。

1.基礎が弱い学生に適した列挙方法

分析:

行数をi、列数をjに設定します。0から数えると0は最初の行を意味し
 ます。112 11102
 次元配列列の数は変わりません。行数iは次のように増加します。
 2 13 1692次元配列列jの数が増加します。行数が変化します。3141682
 次元配列列定数行数iが減少します45672
 次元配列列jが行数の変化

 を減少します。 
 1から12
 と13から16の
 2つのスパイラルがあり
 、1と13は両方とも対角線の位置であることがわかります。
 したがって、各スパイラルの開始位置は対角線上に
 あり、対角線上の行と列は同じインデックスを持ちます。


public class lianxi {
    public static void main(String[] args) {
        //先定义一个二维数组,这里先用4*4的举例
        int[][] arr = new int[4][4];
        Spiral(arr);
    }

    public static void Spiral(int[][] arr) {
        /**我们令行数为i  列数为j  从0开始计数   即0表示第一行
         * 观察可知
         * 1  12  11  10 二维数组    列不变       行数i递增
         * 2  13  16  9二维数组    列数j递增    行数变化
         * 3  14  15  8 二维数组    列不变      行数i递减
         * 4  5   6   7 二维数组    列不j递减    行数变化
         *
         * 并且:
         * 存在2个螺旋
         * 1到12
         * 以及 13到16
         * 我们发现 1和13都在对角线位置
         * 故此 ,每个螺旋的起始位置在对角线上
         * 而 对角线上的数 行列索引相同
         */
        int num = 1;
        for (int j = 0; j < 1; j++) {
            for (int i = 0; i < 3; i++) {
                arr[i][j] = num;
                num++;
            }

        }
        /**
         * 1	0	0	0
         * 2	0	0	0
         * 3	0	0	0
         * 0	0	0	0
         */





        for (int i = 3; i < 4; i++) {
            for (int j = 0; j < 3; j++) {
                arr[i][j] = num;
                num++;
            }

        }
        /**
         * 1	0	0	0
         * 2	0	0	0
         * 3	0	0	0
         * 4	5	6	0
         */


        for (int j = 3; j < 4; j++) {
            for (int i = 3; i >0; i--) {
                arr[i][j] = num;
                num++;
            }

        }
        /**
         * 1	0	0	0
         * 2	0	0	9
         * 3	0	0	8
         * 4	5	6	7
         */


        for (int i = 0; i < 1; i++) {
            for (int j = 3; j > 0; j--) {
                arr[i][j] = num;
                num++;
            }

        }
        /**
         * 1	12	11	10
         * 2	0	0	9
         * 3	0	0	8
         * 4	5	6	7
         */




        for (int j = 1; j < 2; j++) {
            for (int i = 1; i < 3; i++) {
                arr[i][j] = num;
                num++;
            }

        }
        /**
         * 1	12	11	10
         * 2	13	0	9
         * 3	14	0	8
         * 4	5	6	7
         */


        for (int j = 2; j < 3; j++) {
            for (int i = 2; i > 0; i--) {
                arr[i][j] = num;
                num++;
            }

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







        for (int[] row : arr) {
            int cnt=0;
            for (int data : row) {
                cnt++;

                System.out.printf("%d\t", data);
                if (cnt==4){
                    System.out.println();
                }


            }
        }

    }
}

結果:

2.スパイラル正方行列コード

分析:

例として6*6の2次元配列を取り上げます

行数をi、列数をjに設定します。0から数えると、0は最初の行を意味します

1 20 19 18 17 16     
2 21 32 31 30 15     
3 22 33 36 29 14     
4 23 34 35 28 13     
5 24 25 26 27 12     
6 7 8 9 10 11    

各円を4つの円に分割します。たとえば、緑色のボックスには4つの円があります。

最初の円:arr[0][0]から始まる4つの緑色のボックス

第2ラウンド:arr[1][1]から始まる4つの青いボックス

3番目の円:arr[2][2]から始まる4つの黄色いボックス

最初の円をよく見てください

最初の緑色のボックス:  列定数行番号iは    arr[0][0]→arr[4][0]をインクリメントします

2番目の緑色のボックス:  列数jが増加し、行数が変化します  arr[5][0]→arr[5][4]

3番目の緑色のボックス:  列定数行番号iは    arr[5][5]→arr[1][5]をデクリメントします

4番目の緑色のボックス:  列は行数の変更をjデクリメントしません     arr[0][5]→arr[0][1]

自分で分析する

コード:

import java.util.Random;

public class spiral {
    public static void main(String[] args) {

        Random random = new Random();
        //产生一个1-30的随机数
        int n=random.nextInt(30)+1;
        //产生一个1*1至30*30的随机二维数组
        int[][] arr = new int[n][n];

        Spiral(arr);
    }
       public static void Spiral(int[][] arr) {

        int num = 1;//num 表示螺旋里面的数字
        int cnt=0; //cnt 用来记录 下面while循环执行的次数.

        while(true){

          //特殊情况,也就是 当随机数n=1时
            if (arr.length==1){
                arr[0][0]=num;
                break;
            }


            /**我们令行数为i  列数为j  从0开始计数   即0表示第一行
             * 第一个循环表示   二维数组    列不变       行数i递增
             * 第二个循环表示   二维数组    列数j递增    行数变化
             * 第三个循环表示    二维数组    列不变      行数i递减
             * 第四个循环表示   二维数组    列不j递减    行数变化
             */



            //第一个循环表示   二维数组    列不变       行数i递增
          for (int j = cnt; j < 1+cnt; j++) {
            for (int i = cnt; i < arr.length-1-cnt; i++) {
                arr[i][j] = num;
                num++;
            }

        }


          //第二个循环表示   二维数组    列数j递增    行数变化
        for (int i = arr.length-1-cnt; i < arr.length-cnt; i++) {
            for (int j = cnt; j < arr.length-1-cnt; j++) {
                arr[i][j] = num;
                num++;
            }

        }

        //第三个循环表示    二维数组    列不变      行数i递减
        for (int j = arr.length-1-cnt; j < arr.length-cnt; j++) {
            for (int i = arr.length-1-cnt; i >cnt; i--) {
                arr[i][j] = num;
                num++;
            }

        }
        //第四个循环表示   二维数组    列不j递减    行数变化
        for (int i = cnt; i < 1+cnt; i++) {
            for (int j = arr.length-1-cnt; j > cnt; j--) {
                arr[i][j] = num;
                num++;
            }

        }

        //已执行完一圈 cnt++
        cnt++;


        //螺旋已到达矩阵的最中间,可以结束循环
        if (cnt== arr.length/2){


            //当二维数组是奇数矩阵时,最中间会空出一个数
            if (arr.length%2==1){
                arr[arr.length/2][arr.length/2]=num;
            }


            break;
        }
        }



        //遍历二维数组
        for (int[] row : arr) {
            cnt=0;
            for (int data : row) {
                cnt++;

                System.out.printf("%d\t", data);
                //当输出的数字等于数组长度时,换行
                if (cnt==arr.length){
                    System.out.println();
                }


            }
        }


    }
}

結果:

コードはランダムな2次元配列を生成するように設定されているため、スパイラルのマトリックスサイズもランダムです。

おすすめ

転載: blog.csdn.net/Javascript_tsj/article/details/123582705