【原創】生成n*n蛇形矩陣的演算法
本文為原創,如需轉載,請註明作者和出處,謝謝!
在描述演算法之前,先看看下面的5*5的表格:
上面的表格很容易看出規律。就是從左上角第一個格開始(起始為1),然後延右上角到左下角的斜線。先從下到上,再從上到下。開始按數字遞增排列。也就是說每一個斜線上分別有如下幾組數字:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
由於是先從上到下(1可以看做是從上到下),再從下到上,很象一條蛇,因此,該數字表格也可稱為蛇形矩陣。現在要與一個方法(或函式),方法的引數是一個int型別,表示n,方法返回一個二維陣列,表示要獲得的往返接力數字表格。
實際上,這個演算法並不複雜,只需要從分別獲得1至n^2中每個數字對應的二維陣列的座標就可以了。先拿這個5行5列的表格來說,求出上面每組陣列對應的座標(起始位置為0)。
從上面的從標可以看出一個規律。 左上角的半個表格(以對角線分界)的橫座標和縱座標從0開始,每一組增1,直到增至表格的邊界(n - 1),而且是交替的,也就是說,偶數行是列增,行減小,行+列=組的索引。而右下角的4組數字雖然行、列也是交替增長的,但遞減的行或列總是從(n - 1)開始(對於本例,是從4開始),而遞增的行或列總是從index - n + 1開始,其中index表示組的索引。這就可以得出一個演算法。實現程式碼如下:
另一種演算法
上面實現的演算法需要迴圈N*N次才可以生成蛇形矩陣。但仔細分析一下,還可以稍微變換一下這個演算法,使迴圈次數減小至N*N/2。我們上學時曾學過用高斯的方法計算1+2+3+...+100, 1 + 100 = 101,2 + 99 = 101,...,50+51 = 101,因此,結果是101 * 50 = 5050。很方便。我們這個演算法也可採用類似的方法。仔細觀察上面5*5的數字表格發現,算出左上角的矩陣中每一個數字後,都可以直接獲得右下角度某個位置的數字。例如在(0,0)位置的1,可以向到(4,4)位置的25,(1,2)位置的9可以得到(3,2)位置的17。我們發現,每一對數之和都為26。而且它們座標的關係是(row,col),(n - row - 1, n - col - 1)。因此,只要得到左上角的半個矩陣,就可以得出右下角的另外半個矩陣。如果n為奇數,對角線中間的一個數(在5*5的矩陣中是13)與之對應的數是其自身。好,我們看看改進的演算法的實現:
上面的演算法雖然將迴圈次數減少了一半,但每次迴圈的計算量增加了,因此,演算法總體效率並沒有提高。至於使用哪個演算法,可根據實際情況決定。
如果想輸出n=10的數字表格,可以使用int[][] grid = getGrid(10)或int[][] grid1 = getGrid1(10),會得到同樣的結果。輸出grid和grid1,看看是不是下面的結果:
在描述演算法之前,先看看下面的5*5的表格:
1 | 3 | 4 | 10 | 11 |
2 | 5 | 9 | 12 |
19 |
6 | 8 | 13 | 18 | 20 |
7 | 14 | 17 | 21 | 24 |
15 | 16 | 22 | 23 | 25 |
上面的表格很容易看出規律。就是從左上角第一個格開始(起始為1),然後延右上角到左下角的斜線。先從下到上,再從上到下。開始按數字遞增排列。也就是說每一個斜線上分別有如下幾組數字:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
由於是先從上到下(1可以看做是從上到下),再從下到上,很象一條蛇,因此,該數字表格也可稱為蛇形矩陣。現在要與一個方法(或函式),方法的引數是一個int型別,表示n,方法返回一個二維陣列,表示要獲得的往返接力數字表格。
實際上,這個演算法並不複雜,只需要從分別獲得1至n^2中每個數字對應的二維陣列的座標就可以了。先拿這個5行5列的表格來說,求出上面每組陣列對應的座標(起始位置為0)。
第0組 第1組 第2組 第3組 第4組 第5組 第6組 第7組 第8組 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
(0,0) (1,0) (0,1) (0,2) (1,1) (2,0) (3,0) (2,1) (1,2) (0,3) (0,4) (1,3) (2,2) (3,1) (4,0) (4,1) (3,2) (2,3) (1,4) (2,4) (3,3) (4,2) (4,3) (3,4) (4,4) |
從上面的從標可以看出一個規律。 左上角的半個表格(以對角線分界)的橫座標和縱座標從0開始,每一組增1,直到增至表格的邊界(n - 1),而且是交替的,也就是說,偶數行是列增,行減小,行+列=組的索引。而右下角的4組數字雖然行、列也是交替增長的,但遞減的行或列總是從(n - 1)開始(對於本例,是從4開始),而遞增的行或列總是從index - n + 1開始,其中index表示組的索引。這就可以得出一個演算法。實現程式碼如下:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->public static int[][] getGrid(int n)
{
int[][] array = new int[n][n];
int row = 0, col = 0, m = 1;
// 用於控制奇偶組,false表示偶組,true表示奇組
boolean isRow = false;
// i表示當前組的索引,從0開始
for (int i = 0; i < (2 * n - 1); i++)
{
row = i;
while (row >= ((i < n) ? 0 : i - n + 1))
{
// 如果處理的是右下角表格中的數字,行或列最大不能超過n-1
if (row > (n - 1))
row = n - 1;
col = i - row;
if (isRow)
array[row][col] = m;
else // 將row變成列,將col變成行
array[col][row] = m;
m++;
row--;
}
// 切換奇偶組
isRow = !isRow;
}
return array;
}
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->public static int[][] getGrid(int n)
{
int[][] array = new int[n][n];
int row = 0, col = 0, m = 1;
// 用於控制奇偶組,false表示偶組,true表示奇組
boolean isRow = false;
// i表示當前組的索引,從0開始
for (int i = 0; i < (2 * n - 1); i++)
{
row = i;
while (row >= ((i < n) ? 0 : i - n + 1))
{
// 如果處理的是右下角表格中的數字,行或列最大不能超過n-1
if (row > (n - 1))
row = n - 1;
col = i - row;
if (isRow)
array[row][col] = m;
else // 將row變成列,將col變成行
array[col][row] = m;
m++;
row--;
}
// 切換奇偶組
isRow = !isRow;
}
return array;
}
另一種演算法
上面實現的演算法需要迴圈N*N次才可以生成蛇形矩陣。但仔細分析一下,還可以稍微變換一下這個演算法,使迴圈次數減小至N*N/2。我們上學時曾學過用高斯的方法計算1+2+3+...+100, 1 + 100 = 101,2 + 99 = 101,...,50+51 = 101,因此,結果是101 * 50 = 5050。很方便。我們這個演算法也可採用類似的方法。仔細觀察上面5*5的數字表格發現,算出左上角的矩陣中每一個數字後,都可以直接獲得右下角度某個位置的數字。例如在(0,0)位置的1,可以向到(4,4)位置的25,(1,2)位置的9可以得到(3,2)位置的17。我們發現,每一對數之和都為26。而且它們座標的關係是(row,col),(n - row - 1, n - col - 1)。因此,只要得到左上角的半個矩陣,就可以得出右下角的另外半個矩陣。如果n為奇數,對角線中間的一個數(在5*5的矩陣中是13)與之對應的數是其自身。好,我們看看改進的演算法的實現:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->public static int[][] getGrid1(int n)
{
int[][] array = new int[n][n];
int row = 0, col = 0, m = 1;
int number1 = (n * n / 2 + n * n % 2);
int number2 = n * n + 1;
boolean isRow = false;
// number1表示要計算的蛇形矩陣中最大的數字,對於5*5矩陣來說該數是13
for (int i = 0; m < number1; i++)
{
row = i;
while (row >= 0)
{
col = i - row;
if (isRow)
{
array[row][col] = m;
// 填充與m對應的另外一個數
array[n - row - 1][n - col - 1] = number2 - m;
}
else
{
array[col][row] = m;
// 填充與m對應的另外一個數
array[n - col - 1][n - row - 1] = number2 - m;
}
m++;
if(m >= number1) break;
row--;
}
isRow = !isRow;
}
return array;
}
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->public static int[][] getGrid1(int n)
{
int[][] array = new int[n][n];
int row = 0, col = 0, m = 1;
int number1 = (n * n / 2 + n * n % 2);
int number2 = n * n + 1;
boolean isRow = false;
// number1表示要計算的蛇形矩陣中最大的數字,對於5*5矩陣來說該數是13
for (int i = 0; m < number1; i++)
{
row = i;
while (row >= 0)
{
col = i - row;
if (isRow)
{
array[row][col] = m;
// 填充與m對應的另外一個數
array[n - row - 1][n - col - 1] = number2 - m;
}
else
{
array[col][row] = m;
// 填充與m對應的另外一個數
array[n - col - 1][n - row - 1] = number2 - m;
}
m++;
if(m >= number1) break;
row--;
}
isRow = !isRow;
}
return array;
}
上面的演算法雖然將迴圈次數減少了一半,但每次迴圈的計算量增加了,因此,演算法總體效率並沒有提高。至於使用哪個演算法,可根據實際情況決定。
如果想輸出n=10的數字表格,可以使用int[][] grid = getGrid(10)或int[][] grid1 = getGrid1(10),會得到同樣的結果。輸出grid和grid1,看看是不是下面的結果:
1 | 3 | 4 | 10 | 11 | 21 | 22 | 36 | 37 | 55 |
2 | 5 | 9 | 12 | 20 | 23 | 35 | 38 | 54 | 56 |
6 | 8 | 13 | 19 | 24 | 34 | 39 | 53 | 57 | 72 |
7 | 14 | 18 | 25 | 33 | 40 | 52 | 58 | 71 | 73 |
15 | 17 | 26 | 32 | 41 | 51 | 59 | 70 | 74 | 85 |
16 | 27 | 31 | 42 | 50 | 60 | 69 | 75 | 84 | 86 |
28 | 30 | 43 | 49 | 61 | 68 | 76 | 83 | 87 | 94 |
29 | 44 | 48 | 62 | 67 | 77 | 82 | 88 | 93 | 95 |
45 | 47 | 63 | 66 | 78 | 81 | 89 | 92 | 96 | 99 |
46 | 64 | 65 | 79 | 80 | 90 | 91 | 97 | 98 | 100 |
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12921506/viewspace-610503/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 演算法篇-蛇形矩陣演算法矩陣
- 【面試】輸出"蛇形"矩陣面試矩陣
- C++實現蛇形矩陣C++矩陣
- 斐波那契數列的第N項(1≤n≤10^18 矩陣快速冪)矩陣
- 每天OnLineJudge 之 “蛇形矩陣 ”矩陣
- 用C語言輸出蛇形矩陣C語言矩陣
- 1,2,3…n*n 的數字按照順時針螺旋的形式列印成矩陣(遞迴)矩陣遞迴
- 生成螺旋矩陣(方陣、矩陣)矩陣
- “小程式矩陣”時代來臨 “小程式互跳”的N種玩法矩陣
- (原創)一般矩陣 Matrix類矩陣
- 【IDL】獲取n*n陣列的對角線元素的方法陣列
- hdu4328 最大子矩陣問題O(n*m)掃描思想矩陣
- 生成{1,2,...,n}的排列的演算法-組合數學演算法
- 不能使用for迴圈,傳入n和m, 生成一個長度為n,每一項都是m的陣列陣列
- 演算法:N皇后二演算法
- MySQL中資料型別(char(n)、varchar(n)、nchar(n)、nvarchar(n)的區別)MySql資料型別
- O(n^2)的排序演算法排序演算法
- 建立包含N個空物件的陣列物件陣列
- 合併JavaScript陣列的N種方法JavaScript陣列
- (Java) 演算法題:2的N次方Java演算法
- Dynamics CRM實體系列之1:N、N:1以及N:N關係
- 24:蛇形填充陣列陣列
- 獲取陣列第N個元素的方法陣列
- python之矩陣相加:提示使用者輸入矩陣的行數n,再提示使用者輸入矩陣的列數m,接下來,提示使用者輸入 2*n*m 個數字(每次輸入 一個數字)。輸出 C=A+B。Python矩陣
- 演算法學習:矩陣快速冪/矩陣加速演算法矩陣
- 自創open vp n windows步驟Windows
- 演算法-陣列與矩陣演算法陣列矩陣
- 計算2的N次冪n 可輸入,n為自然數
- 生成一個掃雷矩陣矩陣
- Matlab生成隨機矩陣Matlab隨機矩陣
- js生成m-n之間的隨機數JS隨機
- 動態生成一個m行n列的表格
- 演算法 1~n中1的次數演算法
- THREE 矩陣優先原則和平移旋轉矩陣矩陣
- 按字典序生成{1,2,...,n}的r子集的演算法-組合數學演算法
- 如何新增javascript陣列n乘以相同的元素JavaScript陣列
- 求無序陣列總第n大的數陣列
- 從面試題中學演算法(2)---求陣列中唯一n個出現1次的數字(n=1,2,3)面試題演算法陣列