每天一道LeetCode-----将m × n矩阵按照顺时针螺旋顺序转化成一维数组
Spiral Matrix
原題鏈接Spiral Matrix
給定一個m × n矩陣,按照順時針螺旋順序?qū)⒕仃囖D(zhuǎn)化成一維數(shù)組。
螺旋的方向是先從左向右,再從上到下,然后從右到左,最后從下到上。
所以方向可以用{0, 1},{1, 0},{0, -1},{-1, 0}四個方向向量表示。每個方向向量都由行和列構(gòu)成,1表示向右或向下移動,-1表示向左或向上移動,0表示不移動。比方說{0, 1}表示行不移動,列從左向右移動。
可以發(fā)現(xiàn),方向是固定先向右,再向下,然后向左,最后向上,正好對應上面四個方向向量,如果將這四個方向向量存在vector中,那么可以找一個變量記錄方向,即0, 1, 2, 3分別對應上述的方向向量(下標)。每在一個方向上移動完成,就要更換方向,也就是將這個變量加一,不過要記得 % 4
再舉個5 × 3矩陣的例子(m = 5,n = 3)
* * * * * * * * * * * * * * *可以看到,移動的過程是
第一圈
- 向右移動3步
- 向下移動4步
- 向左移動2步
- 向上移動3步
第二圈
- 向右移動1步
- 向下移動2步
結(jié)束
將水平方向移動步數(shù)和垂直方向移動步數(shù)分別提取出來
水平方向
- 向右移動3步
- 向左移動2步
- 向右移動1步
垂直方向
- 向下移動4步
- 向上移動3步
- 向下移動2步
可以看到,在水平方向上,移動的步數(shù)每次都是減一,垂直方向上也是如此。
而初始時,水平方向可以移動3步,也就是列數(shù)n。垂直方向上可以移動4步,是行數(shù)m - 1。
那么就可以使用兩個變量記錄水平方向和垂直方向上下次可以移動多少步。
利用以上兩個條件
- 用方向向量表示當前是應該向哪個方向移動
- 記錄當前方向可以移動多少步
就可以解決問題
代碼如下
class Solution { public:vector<int> spiralOrder(vector<vector<int>>& matrix) {vector<int> res;int nr = matrix.size();if(nr == 0) { return res; }int nc = matrix[0].size();if(nc == 0) { return res; }/* 方向向量 */vector<vector<int>> dirs{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};/* 行/列分別可以移動多少步,初始時行可以移動列數(shù)步,列可以移動行數(shù)-1步 */vector<int> steps{nc, nr - 1};/* [ir, ic]記錄當前的位置,初始為[0, -1] */int ir = 0;int ic = -1;/* idir記錄當前的方向,可以是0,1,2,3 */int idir = 0;/* 如果當前方向上仍然可以移動,就繼續(xù)移動 */while(steps[idir % 2]){/* idir % 2表示是水平還是垂直方向,steps[idir % 2]表示當前方向還可以移動多少步 */for(int i = 0; i < steps[idir % 2]; ++i){/* dirs[idir]表示當前方向 */ir += dirs[idir][0];ic += dirs[idir][1];res.emplace_back(matrix[ir][ic]);}/* 每移動一個方向,對應剩余步數(shù)減一 */--steps[idir % 2];/* 改變方向 */idir = (idir + 1) % 4;}return res;} };Spiral Matrix II
原題鏈接Spiral Matrix II
其實就是上面題的逆序,給出一個一維數(shù)組,按順時針螺旋順序生成一個矩陣,方法一樣
上面兩道題主要是將方向轉(zhuǎn)為方向向量進行解決,因為固定只有四種方向,所以可以用{0, 1}, {1, 0}, {0, -1}, {-1, 0}四個方向向量表示向右,向下,向左和向上四個方向。同時需要用一個變量記錄當前是在哪個方向上,0,1,2,3分別代表四個方向,即作為方向向量的下標。
另外每個方向上的移動是遞減的,每移動一次,這個方向上下次移動的步數(shù)會減一,直到為0為止。
總結(jié)
以上是生活随笔為你收集整理的每天一道LeetCode-----将m × n矩阵按照顺时针螺旋顺序转化成一维数组的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 每天一道LeetCode-----找到给
- 下一篇: 每天一道LeetCode-----将间隔