螺旋矩陣的實現以及代碼優化
螺旋矩陣是指一個呈螺旋狀的矩陣,如下圖所示,就是一個邊長爲5(筆者個人稱一個數字邊長爲1)的螺旋矩陣。
算法思想
1.首先,讀者可以先自行畫出邊長爲3,4,5的螺旋矩陣觀察。不難得出可以將每四個指向箭頭定義成一個圈。
每個圈都是從左到右–從上到下–從右到左–從下到上遞增1。因此,找出每個圈的起始位置,依次往後賦值即可完成此算法。
2.第一個圈的第一個數必爲1。因此可以用它作爲計算其它圈的起始數字。總結規律可以得到:
後一個圈的起始數字 = 前一個圈的起始數字 + 4(前一個圈的邊長 -1);*
算法的Java代碼實現
package com.yuexiang;
import java.util.Scanner;
public class SnakeArray {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入要打印的矩陣邊長:");
int n = scanner.nextInt(); //獲取邊長
int[][] a = new int[n][n]; //定義一個二維數組(矩陣)
int tempN = n; //保存初始邊長
int num = 0; //定義num初始下標
int rowfirst = 1; //定義第一個圈第一個數,固定爲1
int i,j; //循環控制
while(n>0){ //當邊長大於0,繼續賦值
a[num][num]=rowfirst; //給當前圈的初始位置賦值
if (n>1){
for (i=num,j=num+1;j<n+num;j++){ //自左向右
a[i][j]=a[num][num]+j-num;
}
for (i=num+1,j=num+n-1;i<n+num;i++){ //自上向下
a[i][j]=a[i-1][j]+1;
}
for (i=num+n-1,j=num+n-2;j>=num;j--){ //自右向左
a[i][j]=a[i][j+1]+1;
}
for (i=num+n-2,j=num;i>=num+1;i--){ //自下向上
a[i][j]=a[i+1][j]+1;
}
}else {
break;
}
rowfirst = rowfirst+4*(n-1); //計算下一圈的初始數字
n=n-2; //每完成一圈,邊長減2
num++; //初始下標自增1
}
for (i=0;i<tempN;i++){ //打印矩陣
for (j=0;j<tempN;j++){
System.out.print(a[i][j]+" ");
}
System.out.println();
}
}
}
上面的算法雖然實現了功能,但是定義與過程過於繁雜。
下面進行代碼優化
int a[][] = new int[n][n];
int value = 1;
int i=0,j=0;
for (int m=0;m<n/2+n%2;m++)
{
for(j=m,i=m;j<(n-m);j++) //自左向右
{
a[i][j]=value++;
}
for(j--,i++;i<(n-m);i++) //自上向下
{
a[i][j]=value++;
}
for(j--,i--;j>=m;j--) //自右向左
{
a[i][j]=value++;
}
for(i--,j++;i>m;i--) //自下向上
{
a[i][j]=value++;
}
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
System.out.print(a[i][j]+" ");
}
System.out.println();
}
兩相對比,可見第二個代碼定義更加清晰,賦值過程更加明瞭。代碼可讀性也更高。
我們在學習算法時,一定要在寫出程序後繼續思考寫出的算法是否有需要改進的地方,是否能更加簡明的實現。
就說筆者的這第二段程序代碼,也並不是最簡單的實現,還能夠繼續優化。思考一下吧~