1. 程式人生 > >劍指offer之順時針列印矩陣

劍指offer之順時針列印矩陣

題目描述

輸入一個矩陣,按照從外向裡以順時針的順序依次打印出每一個數字,例如,如果輸入如下4 X 4矩陣: 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.

思路

邊界條件參考這篇部落格。個人認為本題目的核心考點在於邊界條件的處理。遍歷矩陣可以近似地視為週期遍歷,即順時針一圈作為一個“週期”,需要藉助4個迴圈,這是問題解決的基本思路。之後,需要藉助4個邊界left、right、top和btm分別是左右上下邊界,而且這是陣列的實際邊界!很明顯,每次遍歷完成後,需要一次“縮圈”的操作,即邊界向中間靠攏。

最外層有一個大的迴圈,這個迴圈用於控制週期遍歷的終止,很明顯可以順利執行的條件是left<right、top<btm。

最後就是特別麻煩的內部週期邊界條件控制了。。。

  1. 從左向右這一個無論如何都要進行列印
  2. 從上到下,需要的邊界是必須至少是兩行才行,因此新增邊界top<btm
  3. 從右到左,需要的邊界是2的基礎上,再保證至少2列,因此邊界條件是top<btm && left<right
  4. 從下之上,需要的邊界是至少2列,同時需要至少3行,因此邊界條件是top+1<btm && left<right

編碼時的邊界條件處理還需要加強!!!!!

AC程式碼

class Solution {
  public:
    vector<int> printMatrix(vector<vector<int> > matrix) {
        vector<int>v;
        if(matrix.empty()) {
            return v;
        }
        int left = 0, right = matrix[0].size() - 1;
        int top = 0, btm = matrix.size() - 1;
        while
(left <= right && top <= btm) { for(int i = left; i <= right; ++i) { v.push_back(matrix[top][i]); } if(top < btm) { for(int i = top + 1; i <= btm; ++i) { v.push_back(matrix[i][right]); } } if(top < btm && left < right) { for(int i = right - 1; i >= left; --i) { v.push_back(matrix[btm][i]); } } if(top + 1 < btm && left < right) { for(int i = btm - 1; i >= top + 1; --i) { v.push_back(matrix[i][left]); } } ++left; --right; ++top; --btm; } return v; } };