1. 程式人生 > >【劍指Offer學習】【面試題20 : 順時針列印矩陣】

【劍指Offer學習】【面試題20 : 順時針列印矩陣】

題目:輸入一個矩陣,按照從外向裡以順時針的順序依次掃印出每一個數字

解題思路:

把列印一圈分為四步:第一步從左到右列印一行,第二步從上到下列印一列,第三步從右到左列印一行,第四步從下到上列印一列。每一步我們根據起始座標和終止座標用一個迴圈就能打印出一行或者一列。

不過值得注意的是,最後一圈有可能退化成只有一行、只有一列,甚至只有一個數字,因此列印這樣的一圈就不再需要四步。圖4.4 是幾個退化的例子, 列印一圈分別只需要三步、兩步甚至只有一步。

這裡寫圖片描述

因此我們要仔細分析列印時每一步的前提條件。第一步總是需要的, 因為列印一圈至少有一步。如果只有一行,那麼就不用第二步了。也就是需要
第二步的前提條件是終止行號大於起始行號。需要第三步列印的前提條件是圈內至少有兩行兩列,也就是說除了要求終止行號大於起始行號之外,還要求終止列號大於起始列號。同理,需要列印第四步的前提條件是至少有三行兩列,因此要求終止行號比起始行號至少大2 , 同時終止列號大於起始列號。

程式碼實現:

public class Test20 {
    /**
     * 輸入一個矩陣,按照從外向裡以順時針的順序依次列印每一個數字
     *
     * @param numbers 輸入的二維陣列,二維陣列必須是N*M的,否則分出錯
     */
    public static void printMatrixClockWisely(int[][] numbers) {
        // 輸入的引數不能為空
        if (numbers == null) {
            return;
        }

        // 記錄一圈(環)的開始位置的行
int x = 0; // 記錄一圈(環)的開始位置的列 int y = 0; // 對每一圈(環)進行處理, // 行號最大是(numbers.length-1)/2 // 列號最大是(numbers[0].length-1)/2 while (x * 2 < numbers.length && y * 2 < numbers[0].length) { printMatrixInCircle(numbers, x, y); // 指向下一個要處理的的環的第一個位置
x++; y++; } } public static void printMatrixInCircle(int[][] numbers, int x, int y) { // 陣列的行數 int rows = numbers.length; // 陣列的列數 int cols = numbers[0].length; // 輸出環的上面一行,包括最中的那個數字 for (int i = y; i <= cols - y - 1; i++) { System.out.print(numbers[x][i] + " "); } // 環的高度至少為2才會輸出右邊的一列 // rows-x-1:表示的是環最下的那一行的行號 if (rows - x - 1 > x) { // 因為右邊那一列的最上面那一個已經被輸出了,所以行呈從x+1開始, // 輸出包括右邊那列的最下面那個 for (int i = x + 1; i <= rows - x - 1; i++) { System.out.print(numbers[i][cols - y - 1] + " "); } } // 環的高度至少是2並且環的寬度至少是2才會輸出下面那一行 // cols-1-y:表示的是環最右那一列的列號 if (rows - x - 1 > x && cols - 1 - y > y) { // 因為環的左下角的位置已經輸出了,所以列號從cols-y-2開始 for (int i = cols - y - 2; i >= y; i--) { System.out.print(numbers[rows - 1 - x][i] + " "); } } // 環的寬度至少是2並且環的高度至少是3才會輸出最左邊那一列 // rows-x-1:表示的是環最下的那一行的行號 if (cols - 1 - y > y && rows - 1 - x > x + 1) { // 因為最左邊那一列的第一個和最後一個已經被輸出了 for (int i = rows - 1 - x - 1; i >= x + 1; i--) { System.out.print(numbers[i][y] + " "); } } } public static void main(String[] args) { int[][] numbers = { {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}, }; printMatrixClockWisely(numbers); System.out.println(); int[][] numbers2 = { {1, 2, 3, 4, 5, 6, 7, 8}, {22, 23, 24, 25, 26, 27, 28, 9}, {21, 36, 37, 38, 39, 40, 29, 10}, {20, 35, 34, 33, 32, 31, 30, 11}, {19, 18, 17, 16, 15, 14, 13, 12}, }; printMatrixClockWisely(numbers2); System.out.println(); int[][] numbers3 = { {1, 2, 3, 4, 5, 6, 7, 8} }; printMatrixClockWisely(numbers3); System.out.println(); int[][] numbers4 = { {1, 2, 3, 4, 5, 6, 7, 8}, {16, 15, 14, 13, 12, 11, 10, 9} }; printMatrixClockWisely(numbers4); System.out.println(); int[][] numbers5 = { {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8} }; printMatrixClockWisely(numbers5); System.out.println(); int[][] numbers6 = { {0, 1}, {15, 2}, {14, 3}, {13, 4}, {12, 5}, {11, 6}, {10, 7}, {9, 8} }; printMatrixClockWisely(numbers6); System.out.println(); int[][] numbers7 = { {1, 2}, {4, 3} }; printMatrixClockWisely(numbers7); System.out.println(); int[][] numbers8 = { {1} }; printMatrixClockWisely(numbers8); System.out.println(); // 0個元素的陣列 printMatrixClockWisely(new int[][]{{}}); // 空陣列 printMatrixClockWisely(null); }

執行結果

這裡寫圖片描述

相關推薦

Offer學習試題20 時針列印矩陣

題目:輸入一個矩陣,按照從外向裡以順時針的順序依次掃印出每一個數字 解題思路: 把列印一圈分為四步:第一步從左到右列印一行,第二步從上到下列印一列,第三步從右到左列印一行,第四步從下到上列印一列。每一步我們根據起始座標和終止座標用一個迴圈就能打印出一

offer學習筆記——試題20時針列印矩陣

題目描述輸入一個矩陣,按照從外向裡以順時針的順序依次打印出每一個數字,例如,如果輸入如下矩陣: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 則依次打印出數字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.解題思路

Offer學習所有試題匯總

tails 超過一半 奇數 正則表達式 detail 刪除 祖先 滑動窗口 翻轉單詞順序 劍指Offer學習   劍指Offer這本書已經學習完了,從中也學習到了不少的東西,現在做一個總的目錄,供自已和大家一起參考,學如逆水行舟,不進則退。只有不斷地學習才能跟上時候,跟得

Offer學習試題5 從尾到頭列印連結串列思路

方案一:(後進先出)遍歷連結串列,再從棧頂開始出個輸出結點的值,此時輸出的結點的順序已經反轉過來了。 先推進棧 再依次取出棧頂元素 方案二:遞迴。 判斷連結串列頭結點是否為空 將 next 結點作為下一次的實參 輸出當前棧頂元素。 缺點:當連結串

Offer學習所有試題彙總

劍指Offer學習   劍指Offer這本書已經學習完了,從中也學習到了不少的東西,現在做一個總的目錄,供自已和大家一起參考,學如逆水行舟,不進則退。只有不斷地學習才能跟上時候,跟得上技術的潮流! 目錄 第01-10題 第11-20題 第21-30題

Offer學習試題4 替換空格思路

題目: 請實現一個函式,將一個字串中的每個空格替換成“%20”。例如,當字串為We Are Happy,則經過替換之後的字串為We%20Are%20Happy。 思路: 遍歷的方向兩邊皆可。 若從後往前遍歷,新的字串需要反轉。 用 String 類的方法判斷字串

Offer學習試題5 從尾到頭列印連結串列

題目:輸入個連結串列的頭結點,從尾到頭反過來打印出每個結點的值。 public class Test05 { /** * 結點物件 */ public s

Offer學習試題26複雜連結串列的複製

題目:請實現函式ComplexListNode clone(ComplexListNode head),複製一個複雜連結串列。在複雜連結串列中,每個結點除了有一個next 域指向下一個結點外,還有一個sibling 指向連結串列中的任意結點或者null。

Offer學習試題56連結串列中環的入口結點

題目:一個連結串列中包含環,如何找出環的入口結點? 解題思路   可以用兩個指標來解決這個問題。先定義兩個指標P1和P2指向連結串列的頭結點。如果連結串列中環有n個結點,指標P1在連結串列上向前移動n步,然後兩個指標以相同的速度向前移動。當第二個指標

Offer學習試題60把二叉樹打印出多行

題目:從上到下按層列印二叉樹,同一層的結點按從左到右的順序列印,每一層列印一行。 解題思路   用一個佇列來儲存將要列印的結點。為了把二叉樹的每一行單獨列印到一行裡,我們需要兩個變數:一個變量表示在當前的層中還沒有列印的結點數,另一個變量表示下一次結

Offer學習試題50樹中兩個結點的最低公共祖先

題目:求樹中兩個結點的最低公共祖先,此樹不是二叉樹,並且沒有指向父節點的指標。 樹的結點定義 private static class TreeNode { int val; List<TreeNode> childre

Offer學習試題67機器人的運動範圍

題目:地上有個m行n列的方格。一個機器人從座標(0,0)的格子開始移動,它每一次可以向左、右、上、下移動一格,但不能進入行座標和列座標的數位之和大於k的格子。 舉例分析   例如,當k為18時,機器人能夠進入方格(35,37),因為3+5+3+7=1

Offer學習試題31連續子陣列的最大和

題目:輸入一個整型陣列,數組裡有正數也有負數。陣列中一個或連續的多個整陣列成一個子陣列。求所有子陣列的和的最大值。要求時間複雜度為O(n)。 例子說明: 例如輸入的陣列為{1, -2, 3, 10, -4, 7, 2, -5},和最大的子陣列為{3,

Offer學習試題54表示數值的字串

題目:請實現一個函式用來判斷字串是否表示數值(包括整數和小數)。 例子說明   例如,字串“+100”,“5e2”,“-123”,“3.1416”及”-1E-16”都表示數值,但“12e”,”1a3.14”,”1.2.3”,”+-5”及“12e+5.

Offer學習試題18 樹的子結構

題目:輸入兩棵二叉樹A 和B,判斷B 是不是A 的子結構。 二叉樹結點的定義: /** * 二叉樹的樹結點 */ public static class BinaryTreeNode { int value; BinaryT

Offer學習試題13 在O(1)時間刪除連結串列結點

程式碼實現: public class Test13 { /** * 連結串列結點 */ public static class ListNode { int value; // 儲存連結串列的值 L

Offer學習試題11 數值的整數次方

程式碼實現: public class Test11 { /** * 實現函式double Power(double base, int exponent),求base的exponent次方。 * 不得使用庫函式,同時不需要考慮大數問題。

Offer學習試題36陣列中的逆序對

題目:在陣列中的兩個數字如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個陣列中的逆序對的總數。 舉例分析   例如在陣列{7, 5, 6, 4 中, 一共存在5 個逆序對,分別是(7, 6)、(7,5),(7, 4)

Offer學習試題28 字串的排列

題目:輸入一個字串,打印出該字串中字元的所有排列。例如輸入字串abc。則打印出由字元a、b、c 所能排列出來的所有字串abc、acb、bac 、bca、cab 和cba 。 解題思路: 把一個字串看成由兩部分組成:第一部分為它的第一個字元,第二部分是後面

Offer學習試題14 調整陣列順序使奇數位於偶數前面

題目:輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有奇數位於陣列的前半部分,所有偶數位予陣列的後半部分。 這個題目要求把奇數放在陣列的前半部分, 偶數放在陣列的後半部分,因此所有的奇數應該位於偶數的前面。也就是說我們在掃描這個陣列的時候, 如