5.11打卡:劍指 offer兩題:順時針打印矩陣/包含min函數的棧

題目描述

輸入一個矩陣,按照從外向裏以順時針的順序依次打印出每一個數字,例如,如果輸入如下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.
解題思路1:順時針打印就是按圈數循環打印,一圈包含兩行或者兩列,在打印的時候會出現某一圈中只包含一行,要判斷從左向右打印和從右向左打印的時候是否會出現重複打印,同樣只包含一列時,要判斷從上向下打印和從下向上打印的時候是否會出現重複打印的情況

思路2:從外到內,一層層打印。難點在於怎麼找到標記點,以及防止重複遍歷。

怎麼找到標記點?對於每一層來說,設左上角的元素座標爲 (i, j),那麼右上角的元素座標爲 (i, n - j - 1),右下角的元素座標是 (m - i - 1 ,n - j - 1),左下角的元素座標是 (m - i - 1, j)。找到標記點後,就是對行/列進行+/-的過程。

怎麼防止重複遍歷?找到四個座標點後,每一層的遍歷可以拆分成 4 個部分。

class Solution {
public:
    vector<int> printMatrix(vector<vector<int> > matrix) {
        
        //解法1:
        vector<int> res; //定義一維數組
        int m = matrix.size(), n = matrix[0].size(); //定義行爲m,列爲n
        vector<vector<bool>> st(m,vector<bool>(n,false)); //定義一個二維bool型數組,判定是否數組訪問過
        int dx[4]={0,1,0,-1}, dy[4]={1,0,-1,0}; //定義上左下右
        int x = 0, y = 0 ,d = 0; //從(0,0)開始遍歷,d = 0表示先從右邊開始
        for (int i = 0; i < n * m; i ++) { //訪問n*m次
            res.push_back(matrix[x][y]); //將訪問的數保存至res一維數組
            st[x][y] = true; //將訪問的數定義爲false
            int a = x + dx[d], b= y + dy[d];
            if (a < 0 || a >= m || b < 0 || b >= n || st[a][b] ) {
                d = (d + 1) % 4;
                a = x + dx[d], b = y + dy[d];
            }
            x = a, y = b;
        }
        return res;
        /*解法2:
        vector<int>res;
        res.clear();
        int row=matrix.size();//行數
        int collor=matrix[0].size();//列數
        //計算打印的圈數
        int circle=((row<collor?row:collor)-1)/2+1;//圈數
        for(int i=0;i<circle;i++){
            //從左向右打印
            for(int j=i;j<collor-i;j++)
                res.push_back(matrix[i][j]);         
            //從上往下的每一列數據
            for(int k=i+1;k<row-i;k++)
                res.push_back(matrix[k][collor-1-i]);
            //判斷是否會重複打印(從右向左的每行數據)
            for(int m=collor-i-2;(m>=i)&&(row-i-1!=i);m--)
                res.push_back(matrix[row-i-1][m]);
            //判斷是否會重複打印(從下往上的每一列數據)
            for(int n=row-i-2;(n>i)&&(collor-i-1!=i);n--)
                res.push_back(matrix[n][i]);}
        return res;*/
    }
};

包含min函數的棧

題目描述

定義棧的數據結構,請在該類型中實現一個能夠得到棧中所含最小元素的min函數(時間複雜度應爲O(1))。

注意:保證測試中不會當棧爲空的時候,對棧調用pop()或者min()或者top()方法。

思路:定義兩個棧,棧1實現基本功能,棧2保存當前棧狀態的最小值
壓棧:壓棧時若壓入值小於棧2的棧頂,將改值壓入棧2
出棧:出棧時若棧頂值等於棧2棧頂,棧2也隨之出棧
當前棧的最小值即爲棧2棧頂值

class Solution {
public:
    stack<int> stk, mm;
    void push(int value) {
        stk.push(value);
        if(mm.empty() || value < mm.top())
            mm.push(value);
    }
    void pop() {
        if(!stk.empty()){
            if(mm.top()==stk.top())
                mm.pop();
            stk.pop();
        }
    }
    int top() {
        if(stk.empty()) return 0;
        return stk.top();
    }
    int min() {
        if(stk.empty()) return 0;
        return mm.top();
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章