本文為原創,如需轉載,請注明作者和出處,謝謝!
在描述算法之前,先看看下面的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表示組的索引。這就可以得出一個算法。實作代碼(Java版)如下:
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=10的數字表格,可以使用int[][] grid = getGrid(10);,輸出這個grid,看看是不是下面的結果:
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
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
哪位還有更好的算法,請跟貼。可以使用任何語言實作。
本文轉自銀河使者部落格園部落格,原文連結http://www.cnblogs.com/nokiaguy/archive/2009/07/24/1530139.html如需轉載請自行聯系原作者
銀河使者