算法(18)給女朋友講明白校招時的面試題,【回形矩陣、回形取數】

寫在前面: 我是 揚帆向海,這個暱稱來源於我的名字以及女朋友的名字。我熱愛技術、熱愛開源、熱愛編程。技術是開源的、知識是共享的

這博客是對自己學習的一點點總結及記錄,如果您對 Java算法 感興趣,可以關注我的動態,我們一起學習。

用知識改變命運,讓我們的家人過上更好的生活


今天下午女朋友去參加了校園招聘會,回來的時候垂頭喪氣!

在這裏插入圖片描述

:面試怎麼樣?(原諒咱們都是理工科直男)

: 。。。

: 面試有沒有做筆試題?

:做了

:什麼題?

:一道算法題

:你大概說說題目

:是一道回形取數的算法題

: 哦。。。這題不至於哭吧!

在這裏插入圖片描述

一、題目分析

輸入一個整數,則以該數字爲矩陣的大小,把1,2,3…n*n 的數字按照順時針螺旋的形式填入其中。

例如:

輸入數字2,則程序輸出:
1 2
4 3

輸入數字3,則程序輸出:
1 2 3
8 9 4
7 6 5

二、算法分析

回形取數就是沿矩陣的邊取數,若當前方向上無數可取或已經取過,則旋轉90度。一開始位於矩陣左上角,方向向右。按順時針方向旋轉進行取值。

類似於貪吃蛇,碰到 障礙 或 邊界 就要改變方向

在這裏插入圖片描述
先不急,我來給你畫一張圖,慢慢分析:

每一個數字當作矩陣中的一個點,輸出順序是從外圈到內圈的順時針順序。以最外圈爲例,其輸出爲從(0,0)到(2,0)爲紅色點,其次輸出是黃色點,再次輸出是藍色點,最後輸出是綠色點,按照順時針的順序,到此外圈輸出完畢。

從(0,0)點開始,開始向右取值,可以畫出這樣的圖形
在這裏插入圖片描述

從上面的圖形我們發現如下規律

x 表示列, y 表示行

輸出 規律
輸出第一條線上線(紅色)的時候 x 逐次加一,y 不變
輸出第二條線右線(黃色)的時候 y 逐次加一,x 不變
輸出第三條線下線(藍色)的時候 x 逐次減一,y 不變
輸出第四條線左線(綠色)的時候 y 逐次減一,x 不變

通過以上的規律,每次輸出都需要更換不同的起始點,可以通過4個 for 循環依次輸出紅色、黃色、藍色、綠色四個點,直至全部輸完。

關於輸出矩陣,大多數人都會認爲使用數組最爲方便,所以這裏使用二維數組來實現。

使用一個二維數組 array 來存放數據,最後遍歷輸出這些數據
在這裏插入圖片描述

第一圈輸出完畢後,又會按上述規律循環輸出第二圈。。。

:明白了沒?

:明白了

:那你寫一下代碼,實現上面說說的邏輯

她噼裏啪啦一頓操作就寫完了(此處代碼有bug,望耐心看完後面的)


public class RectangleTest {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("請輸入矩陣階數:");
        int n = scanner.nextInt();
        printRectangle(n);
    }

	 /**
     * 回形矩陣
     *
     * @param n
     */
    private static void printRectangle(int n) {
        // 創建一個二維數組
        int[][] array = new int[n][n];
        // num 表示第幾個數字
        int num = 1;

        // 外層循環 i 控制圈數,內層循環 j 控制第幾條線
        for (int i = 0; i < n / 2; i++) {
            // 第一條線 上線
            // x 表示列, y 表示行
            for (int y = i, x = i; x < n - i - 1; x++) {
                array[y][x] = num++;
            }
            // 第二條線 右線
            for (int y = i, x = n - i - 1; y < n - i - 1; y++) {
                array[y][x] = num++;
            }
            // 第三條線 下線
            for (int y = n - i - 1, x = n - i - 1; x > i; x--) {
                array[y][x] = num++;
            }
            // 第四條線 左線
            for (int y = n - i - 1, x = i; y > i; y--) {
                array[y][x] = num++;
            }
        }
        
        // 遍歷打印輸出數字
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array.length; j++) {
                System.out.print(array[i][j] + "\t");
            }
            System.out.println();
        }
    }
}

這是她寫的代碼,我讓測試一下

在這裏插入圖片描述
她感覺很開心,我說你再輸入一個3或5,再測試一下

在這裏插入圖片描述

:發現沒,當輸入的數字是奇數的時候,中間數字有問題。

:是不是可以做個判斷,對輸入的數字進行區分,當N階矩陣是一個偶數階的矩陣時沒有矩陣中心元素,但是奇數階矩陣有矩陣中心元素

:直接輸出最後那個數字。。。

if (n % 2 == 1) {
	array[n / 2][n / 2] = num;
}

三、完整的代碼實現

public class RectangleTest {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("請輸入矩陣階數:");
        int n = scanner.nextInt();
        printRectangle(n);
    }

	 /**
     * 回形矩陣
     *
     * @param n
     */
    private static void printRectangle(int n) {
        // 創建一個二維數組
        int[][] array = new int[n][n];
        // num 表示要顯示的數字
        int num = 1;

        // 外層循環 i 控制圈數,內層循環 j 控制第幾條線
        for (int i = 0; i < n / 2; i++) {
            // 第一條線 上線
            // x 表示列, y 表示行
            for (int y = i, x = i; x < n - i - 1; x++) {
                array[y][x] = num++;
            }
            // 第二條線 右線
            for (int y = i, x = n - i - 1; y < n - i - 1; y++) {
                array[y][x] = num++;
            }
            // 第三條線 下線
            for (int y = n - i - 1, x = n - i - 1; x > i; x--) {
                array[y][x] = num++;
            }
            // 第四條線 左線
            for (int y = n - i - 1, x = i; y > i; y--) {
                array[y][x] = num++;
            }
        }

        // 對輸入的階數進行判斷
        if (n % 2 == 1) {
            array[n / 2][n / 2] = num;
        }

        // 遍歷打印輸出數字
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array.length; j++) {
                System.out.print(array[i][j] + "\t");
            }
            System.out.println();
        }
    }
}

測試結果:

在這裏插入圖片描述


由於水平有限,本博客難免有不足,懇請各位大佬不吝賜教!

發佈了89 篇原創文章 · 獲贊 2181 · 訪問量 32萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章