天天看点

关于矩阵数字的两个有趣问题

昨天看见网上有两个贴子,关于矩阵数字的问题,仔细发现两个试题的算法很相似。

问题1

当参数是1就输出

1

当参数是2就输出

222

212

222

当参数是3就输出

33333

32223

32123

32223

33333

问题2

int i=5; 

1   2   3   4  5 

16 17 18 19 6 

15 24 25 20 7 

14 23 22 21 8 

13 12 11 10 9 

int i=6 

  1   2   3   4     5   6 

20 21 22 23 24   7 

19 32 33 34 25   8 

18 31 36 35 26   9 

17 30 29 28 27 10 

16 15 14 13 12 11 

分析

仔细看看两个试题,算法其实很相似,如下图所示。

关于矩阵数字的两个有趣问题

1. 可分解成一圈一圈的,每一圈的规律都相同,如红色圈与黄色圈、蓝色圈遵循相同的规律,如图G1和G2;

2. G1的每一圈用相同的数字填充,而G2的每一圈则依次递增,递增步长为1;

3. 先初始化最外圈,再缩小一圈,直到最后一圈(或最中心,第2题视奇数和偶数不同);如图G1-1, G1-2, G1-2和G2-1, G2-2, G2-2;

4. 每一圈初始化的时候,可分解为四个边,每个边的规律也是相同的,G1-1值不变,G2-1依次递增,步长为1;

5. 第一边初始化的时候,依照红、黄、蓝、绿的顺序依次,如图G1-1和G2-1;

6. 依照上述规律,可以通过递归方法简单实现;当然,这只是其中的一种方法,只是有趣而已;

代码如下:

public class ArrayTest {

    public static int[][] getArray1(int n){

        int[][] a = null;

        int lenght = (n-1)*2+1;

        if(n<=0){

            return null;

        }else if(n == 1){

            a = new int[1][1];

            a[0][0] = n;

            show(a);

        }

        else{

            a = new int[lenght][lenght];

            for( int i=0; i<lenght-1; i++){

                a[0][i] = n;         // red

                a[i][lenght-1] = n;        // yellow

                a[lenght-1][lenght-1-i] = n;    // blue                       

                a[lenght-1-i][0] = n;    // green

            }

            show(a);

            int[][] inside = getArray1(n-1);

            if( null != inside){

                for(int x=0; x<inside.length;x++){

                    for(int y=0; y<inside[x].length;y++){

                        a[x+1][y+1] = inside[x][y];

                    }

                }

            }

        }

        return a;

    }

    public static int[][] getArray2(int n, int start){

        int[][] a = null;

        int step = 0;

        if(n<=0){

            return null;

        }else if( n==1 ){

            a = new int[1][1];

            a[0][0] = start;

            show(a);

        }else{

            a = new int[n][n];

            for( int i=0; i<n-1; i++){

                a[0][i] = start + step++;               

            }           

            for( int i=0; i<n-1; i++){

                a[i][n-1] = start + step++;           

            }

            for( int i=0; i<n-1; i++){

                a[n-1][n-1-i] = start + step++;               

            }

            for( int i=0; i<n-1; i++){

                a[n-1-i][0] = start + step++;       

            }

            show(a);

            int[][] inside = getArray2(n-2, start+step);

            if( null != inside){

                for(int x=0; x<inside.length;x++){

                    for(int y=0; y<inside[x].length;y++){

                        a[x+1][y+1] = inside[x][y];

                    }

                }

            }

        }

        return a;

    }

    private static void show(int[][] a){

        if(null == a) return;

        int max = 0;

        for(int i=0; i<a.length;i++){

            for(int j=0; j<a[i].length;j++){

                if(a[i][j]>max) max=a[i][j];

            }

        }

        for(int i=0; i<a.length;i++){

            for(int j=0; j<a[i].length;j++){

                System.out.print(formatVale(a[i][j],String.valueOf(max).length()));

            }

            System.out.println();

        }

    }

    private static String formatVale(int value, int length){

        StringBuilder sb = new StringBuilder();

        String idstr = String.valueOf(value);

        int idlength = idstr.length();

        for(int i=0; i<length-idlength;i++){

            sb.append(' ');

        }

        sb.append(' ');

        sb.append(idstr);

        return sb.toString();

    }

    public static void main(String[] args) {

        int[][] a1 = getArray1(3);

        show(a1);

        int[][] a2 = getArray2(5,1);

        show(a2);

    }

}

继续阅读