1. 程式人生 > 實用技巧 >面試題:Java回形陣列

面試題:Java回形陣列

最近遇到一個面試題。

給定一個數字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;
    }
}