最近遇到一個面試題。
給定一個數字n,輸出一個n階矩陣。矩陣中的元素為1到n²。按回形排列
eg1 :
輸入:n=2
輸出:
1 2
4 3
eg2:
輸入:n=3
輸出:
1 2 3
8 9 4
7 6 5
思路:
這個題屬於現實中遇到很簡單,但是程序實現還是有些難度的問題。
面試的時候面試官讓我手寫出這個問題的解法,無奈最后實在沒寫出來。紙上寫代碼太難了。
這個問題其實需要分成三個層次去看。
第一層看出來,此問題需要一個二維數組解決
第二層看出來,此問題一個有四種操作數組的情況
第三層看出來,此問題可以按層次操作。
明白這三層思路,那就能解決問題了。但是還是有幾個邊界問題需要處理
1. 如何划分四種操作的操作范圍
這個問題其實看你的習慣,我這里是按平均分配的原則分配給了四次操作。每次操作處理n-1-當前層數
次
2. n為奇數的時候,最內層只有一個元素。此時按下面方法無法被處理。因此如果n為奇數時直接將最內層的填充為n*n
代碼
public class Solution {
/**
* 二維數組輸出工具
*
* @param arr 二維數據
* @param length 補齊長度
*/
static void print(int[][] arr, int length) {
for (int[] ints : arr) {
for (int anInt : ints) {
System.out.print(getLengthSpace(anInt, length));
}
System.out.println();
}
}
/**
* 補齊空格工具類
*
* @param num 元素
* @param length 補齊的長度
* @return 補齊之后的元素
*/
static String getLengthSpace(int num, int length) {
StringBuilder result = new StringBuilder(String.valueOf(num));
int size = length - result.length() + 1;
for (int i = 0; i < size; i++) {
result.append(" ");
}
return result.toString();
}
public static void main(String[] args) {
print(fun(100), 5);
}
/**
* 回形數組構建
*
* @param n 階數
* @return n階數組
*/
static int[][] fun(int n) {
int[][] arr = new int[n][n];
int start = 1;
//當前構建的層數,默認為0
int layer = 0;
//如果n為偶數則遍歷n/2此,若n為奇數則需要遍歷n/2+1次。
for (int i = 0; i < (n / 2 + n % 2); i++) {
//水平向右填充
for (int first = layer; first < n - 1 - layer; first++) {
arr[layer][first] = start++;
}
//垂直向下填充
for (int second = layer; second < n - 1 - layer; second++) {
arr[second][n - layer - 1] = start++;
}
//水平向左填充
for (int third = n - layer - 1; third > layer; third--) {
arr[n - layer - 1][third] = start++;
}
//垂直向上填充
for (int forth = n - layer - 1; forth > layer; forth--) {
arr[forth][layer] = start++;
}
//進行下一層遍歷
++layer;
}
//n為奇數的時候,數組最中間的元素無法被填寫。因此手動填充為n*n
if (n % 2 != 0) {
int mid = n >> 1;
arr[mid][mid] = n * n;
}
return arr;
}
}