目录

​​螺旋方阵介绍​​

​​1.适合基础薄弱同学的 列举法​​

​​2.螺旋方阵代码​​


螺旋方阵介绍

所谓“螺旋方阵”,是指对任意给定的N,将1到N×N的数字从左上角第1个格子开始,按顺时针螺旋方向顺序填入N×N的方阵里。这里,我给大家写逆时针的 例如下图:

螺旋方阵(列举法,分治法,java版,逆时针)_数据结构

1.适合基础薄弱同学的 列举法

分析:


我们令行数为i 列数为j 从0开始计数 即0表示第一行 观察可知 1 12 11 10 二维数组 列不变 行数i递增 2 13 16 9 二维数组 列数j递增 行数变化 3 14 16 8 二维数组 列不变 行数i递减 4 5 6 7 二维数组 列不j递减 行数变化 并且: 存在2个螺旋 1到12 以及 13到16 我们发现 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();
}


}
}

}
}

结果:

螺旋方阵(列举法,分治法,java版,逆时针)_推荐算法_02

2.螺旋方阵代码

分析:

以6*6二维数组举例


我们令行数为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    


螺旋方阵(列举法,分治法,java版,逆时针)_逻辑回归_03

我们把每圈圈分成:四个循环,就例如绿框有4个。

第一圈:4个绿框, 从arr[0][0]开始

第二圈:4个蓝框, 从arr[1][1]开始

第三圈:4个黄框, 从arr[2][2]开始

再细看第一个圈

第一个绿框:  列不变 行数i递增    arr[0][0]→arr[4][0]

第二个绿框:  列数j递增 行数变化  arr[5][0]→arr[5][4]

第三个绿框:  列不变 行数i递减    arr[5][5]→arr[1][5]

第四个绿框:  列不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();
}


}
}


}
}

结果:

因为我们代码中设置了产生随机二维数组,故此螺旋的矩阵大小也是随机的

螺旋方阵(列举法,分治法,java版,逆时针)_逻辑回归_04

螺旋方阵(列举法,分治法,java版,逆时针)_算法_05