今天参加了腾讯实习生的在线笔试,螺旋矩阵的问题,算是ACM的入门题吧
想到了有两种实现递归和非递归
输入:3
输出:
1 2 3 8 9 4 7 6 5
输入:5
输出:
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
package com.bonult.algorithm;
import java.util.Scanner;
/**
* @author bonult
*
*/
public class HelixMatrix {
public static void main(String[] args) {
int i, j, n;
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
sc.close();
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
System.out.print(String.format("%2d ", calculate(n-1, i, j)));
}
System.out.println();
}
}
// 递归求解
private static int calculate(int basic, int n, int i, int j) {
if (0 == i) {
return basic + j + 1;
} else if (n - 1 == j) {
return basic + n + i;
} else if (n - 1 == i) {
return basic + 2 * (n - 1) + n - j;
} else if (0 == j) {
return basic + 3 * (n - 1) + n - i;
} else {
return calculate(basic + 4 * (n - 1), n - 2, i - 1, j - 1);
}
}
// 非递归求解
private static int calculate(int n, int i, int j) {
// (i, j)位置的数值
int k = 0;
// 用来计算(i, j)的外有几个完整的“圈”
int mini = i < n - i ? i : n - i;
int minj = j < n - j ? j : n - j;
int min = mini < minj ? mini : minj;
int h;
// h用来控制层数
for (h = 0; h < min; ++h) {
// 内层的圈要比临近外层的圈的边长小2
k += (n - 2 * h) * 4;
}
// (i, j)位于同层的上方
if (i == min) {
// 直接取得j坐标的位置,注意需要减掉min,因为外围已经计算过了
k += j - min + 1;
}
// (i, j)位于同层的右侧
else if (j == n - min) {
// 需要加上上方边长的长度
k += (n - 2 * min) + (i - min) + 1;
}
// (i, j)位于同层的下方
else if (i == n - min) {
// 需要加上上方和右侧的长度
k += (n - 2 * min) * 2 + (n - min - j) + 1;
}
// (i, j)位于同层的左侧
else if (j == min) {
// 需要加上上方、右侧和下方的长度
k += (n - 2 * min) * 3 + (n - min - i) + 1;
}
return k;
}
}