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

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

问题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 {

    /*
     * n = 3
     *  3 3 3 3 3
     *  3 2 2 2 3
     *  3 2 1 2 3
     *  3 2 2 2 3
     *  3 3 3 3 3
     */
    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];
            /*
             * initial the bytes's circumference with value n
             */
            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);
            /*
             * copy inside bytes             
             */
            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;
    }
   
    /*
     * n = 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
     */
    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];
            /*
             * initial the bytes's circumference with start+step
             * step 1: init red
             * step 2: init yellow
             * step 3: init blue
             * step 4: init green
             * Of course you can init within 1 for loop, but it less readable
             */
            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);
           
            /*
             * copy inside bytes             
             */
            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);

    }

}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值