算法学习———Java实现螺旋数组

让我们先来认识一下什么是螺旋数组。

形如  和 这种 按顺序输入的二维数组,会以顺时针螺旋排列 输出。

我们现在希望输入一个整数 n ,建立一个 n x n 的螺旋数组并输出。

例如 我们输入3 输出

 OK,让我们开始分析一下。

每一次放入数组的顺序数字很好实现,每次加一即可。

难点在于放入数组的数字需要拐弯,这样放入的顺序问题。

对于这样的问题,我们可以定义一个变量,让他表示放入数字的方向,

观察可得到我们每个螺旋数组都是先向右创建,再向下创建

在这里我们使用 0代表向下 , 1代表向左 , 2代表向上 , 3代表向右,每次改变,这个变量加一取余

我们在以4x4的螺旋数组为例子分析。

 我们可以认为,在创建的第一步,将第一行的4个数字( 1,2,3,4)输出;第二步,输出第四列的3个数字(5,6,7);第三步,打印第4行的3个数字(8,9,10);第四步,打印第一列的2个数字(11,12);第五步,打印第2行的两个数字(13,14);第六步打印第3列的1个数字(15);第七部打印第3行的一个数字(16)。

对以上过程进行总结规律,可以得出,在第一步的时候,向右打印n个数字,第二步第三步,向下和向左的分别打印 n -1 个数字,第四步第五步,向上向右分别打印 n-2 个数字。 将第一步除外,向下和向左打印的数字个数一样,,向上和向右打印的数字个数一样。由此我们可以实现如下代码。


package cn.baokx;
 
public class Test {
	public static void main(String[] args) {
		printArray(getSpiralArray(5,5,false));
		System.out.println("**************");
		printArray(getSpiralArray(5,5,true));
	}
	//返回螺旋数组
	public static int [][] getSpiralArray(int m,int n,boolean reverse){
		//定义一个长度为m*n的数组,并按顺序初始化
		int [] numArray = new int[m*n];
		for(int i = 0 ; i < numArray.length ; i++){
			if(!reverse){
				numArray[i] = (i+1);
			}else{
				numArray[i] = (numArray.length-i);
			}
		}
		//初始化数组下标
		int foot = 0;
		
		//声明螺旋数组
		int[][] array = new int[m][n];
		//计算"层数",以m和n中较小的数为准
		int layer = m<n?m:n;
		layer = (layer%2==1)?(layer / 2 + 1):(layer / 2);
		
		// 从外层到里层循环
		for (int i = 0; i < layer; i++) { 
			//从左到右
			for (int j = i; j < n - i; j++) {
				array[i][j] = numArray[foot++];
				if(foot>=m*n){
					return array;
				}
			}
			// 从上到下
			for (int j = i + 1;  j < m - i; j++) {
				array[j][n - i - 1] = numArray[foot++];
				if(foot>=m*n){
					return array;
				}
			}
			// 从右到左
			for (int j = n - i - 2; j >= i; j--) {
				array[m - i - 1][j] = numArray[foot++];
				if(foot>=m*n){
					return array;
				}
			}
			// 从下到上
			for (int j = m - i - 2; j > i; j--) {
				array[j][i] = numArray[foot++];
				if(foot>=m*n){
					return array;
				}
			}
		}
		return array;
	}
	//打印二维数组
	public static void printArray(int [][] array){
		for (int i = 0; i < array.length; i++) {
			for (int j = 0; j < array[0].length; j++) {
	  			if(array[i][j]<10){
	  				System.out.print("0");
	  			}
	  			System.out.print(array[i][j] + " ");
			}
			System.out.println();
		} 
	}
}

第二张实现方式:

public class SpiralMatrix {

    public static void main(String[] args) {
        printArray(geneSpiralMatrix(5, 5));
        System.out.println(Arrays.deepToString(geneSpiralMatrix(5, 5)));
    }

    public static int[][] geneSpiralMatrix(int m, int n) {
        int[][] matrix = new int[m][n];
        if (m * n <= 0) {
            return matrix;
        }
        int up = 0, down = m - 1;
        int left = 0, right = n - 1;
        int num = 1;

        while (num <= m * n) {
            //从左到右
            for (int i = up; i <= right; i++) {
                matrix[up][i] = num++;
            }
            up++;
            //从上到下
            for (int i = up; i <= down; i++) {
                matrix[i][right] = num++;
            }
            right--;
            //从右到左
            for (int i = right; i >= left; i--) {
                matrix[down][i] = num++;
            }
            down--;

            //从下到上
            for (int i = down; i >= up; i--) {
                matrix[i][left] = num++;
            }
            left++;
        }

        return matrix;

    }

    public static void printArray(int[][] array) {

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

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值