leetcode-54. Spiral Matrix - Medium

descrition

GGiven a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.

For example,
Given the following matrix: [
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
You should return [1,2,3,6,9,8,7,4,5].

解析

基本思路是按照规则一个个的取数,两份方法的区别在于处理的技巧不同。

方法 1:

小技巧(si,sj),(ei, ej),对角线可以唯一确定一个矩阵。循环获取结果,每次循环获取当前最外层的一圈数字。

  1. 从左到右,matrix[si][sj,...,ej]
  2. 从上到下,matrix[si,...,ej][ej]
  3. 从右到左,matrix[ei][ej-1,...,sj]
  4. 从下到上,matrix[ei-1,...,si-1][sj]

实现如代码所示,注意边界条件。

方法 2:

我们只需要模拟时钟的顺时针行走,每走一步获取一个元素,假设矩阵 matrix 有 m 行 n 列,那么只需要循环 m * n 次即可获取所有元素。算法描述如下:

定义两个辅助数组变量如下,dr 和 dc 分别表示行和列的方向变化。

dr={0, 1, 0, -1}
dc={1, 0, -1, 0}

两个数组共同组合有以下 4 种情况:

  1. dr[0], dc[0]:行的增量为 0,列的增量为 1,对应方法 1 的情况 1
  2. dr[1], dc[1]:行的增量为 1,列的增量为 0,对应方法 1 的情况 2
  3. dr[2], dc[2]:行的增量为 0,列的增量为 -1, 对应方法 1 的情况 3
  4. dr[3], dc[3]:行的增量为 -1,列的增量为 0,对应方法 1 的情况 4

我们总共遍历 m * n 次,每次获取一个元素,而没个元素的状态都将是以上 4 种状态中的一种。令 r,c 分别表示当前的行和列的下标,cr, cc 分别表示 candidate,即下一个候选位置的下标,di 表示当前的方向(对应以上 4 种情况,即 dr,dc 的下标),visited[][] 对应 matrix,表示元素是否被访问过。

对于任意一次遍历,若 r,c 合法,即没有超出矩阵边界又没有被访问过,那么我们可以获取当前元素。否则,我们需要调换方向,即更新 di 的值,具体实现参考代码。

实际上方法 2 不是最优解,相比于方法 1, 方法 2 需要一个辅助的数组,但其思想非常值得借鉴,尤其是状态控制的 dr[] 和 dc[] ,di

leetcode-solution

code

#include <iostream>
#include <vector>
#include <algorithm> using namespace std; class Solution{
public:
vector<int> spiralOrder(vector<vector<int> >& matrix){ //return spiralOrderCycle(matrix);
return spiralOrderSimilation(matrix); } // time-O(m*n), space-O(1) exclude the space used to return info.
vector<int> spiralOrderCycle(vector<vector<int> >& matrix){
vector<int> ans;
if(matrix.empty())
return ans; int rows = matrix.size(), cols = matrix[0].size();
int si = 0, sj = 0;
int ei = rows - 1, ej = cols - 1; while(si <= ei && sj<=ej){
spiralOrderOneCycle(matrix, si, sj, ei, ej, ans);
si++;
sj++;
ei--;
ej--;
} return ans;
} void spiralOrderOneCycle(vector<vector<int> >& matrix,
int si, int sj, int ei, int ej,
vector<int>& ans){
// top row
for(int j=sj; j<=ej; j++)
ans.push_back(matrix[si][j]); // right column
for(int i=si+1; i<=ei; i++)
ans.push_back(matrix[i][ej]); // down row if exist
if(si < ei){
for(int j=ej-1; j>=sj; j--)
ans.push_back(matrix[ei][j]);
} // left column if exist
if(sj < ej){
for(int i=ei-1; i>si; i--)
ans.push_back(matrix[i][sj]);
}
} // time-O(m*n), space=O(m*n)
vector<int> spiralOrderSimilation(vector<vector<int> > &matrix){
vector<int> ans;
if(matrix.empty())
return ans;
int rows = matrix.size(), cols = matrix[0].size();
vector<vector<bool> > visited(rows, vector<bool>(cols, false));
int dr[] = {0, 1, 0, -1};
int dc[] = {1, 0, -1, 0};
// start from the left-top corner (r,c) = (0,0) and from left to right
// di = 0, dr[0] and dc[0], correspond left to right.
int di = 0, r = 0, c = 0; for(int i=0; i<rows*cols; i++){
ans.push_back(matrix[r][c]);
visited[r][c] = true;
int cr = r + dr[di];
int cc = c + dc[di];
if(0 <= cr && cr < rows && 0 <= cc && cc < cols && !visited[cr][cc]){
r = cr;
c = cc;
}else{
// change direction
di = (di + 1) % 4;
r = r + dr[di];
c = c + dc[di];
}
} return ans;
}
}; int main()
{
return 0;
}

[array] leetcode - 54. Spiral Matrix - Medium的更多相关文章

  1. Leetcode 54. Spiral Matrix & 59. Spiral Matrix II

    54. Spiral Matrix [Medium] Description Given a matrix of m x n elements (m rows, n columns), return ...

  2. LeetCode - 54. Spiral Matrix

    54. Spiral Matrix Problem's Link ------------------------------------------------------------------- ...

  3. leetcode 54. Spiral Matrix 、59. Spiral Matrix II

    54题是把二维数组安卓螺旋的顺序进行打印,59题是把1到n平方的数字按照螺旋的顺序进行放置 54. Spiral Matrix start表示的是每次一圈的开始,每次开始其实就是从(0,0).(1,1 ...

  4. Leetcode 54:Spiral Matrix 螺旋矩阵

    54:Spiral Matrix 螺旋矩阵 Given a matrix of m x n elements (m rows, n columns), return all elements of t ...

  5. leetCode 54.Spiral Matrix(螺旋矩阵) 解题思路和方法

    Spiral Matrix Given a matrix of m x n elements (m rows, n columns), return all elements of the matri ...

  6. LeetCode: 54. Spiral Matrix(Medium)

    1. 原题链接 https://leetcode.com/problems/spiral-matrix/description/ 2. 题目要求 给定一个二维整型数组,返回其螺旋顺序列表,例如: 最后 ...

  7. LeetCode 54. Spiral Matrix(螺旋矩阵)

    Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral or ...

  8. [leetcode]54. Spiral Matrix螺旋矩阵

    Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral or ...

  9. [leetcode]54. Spiral Matrix二维数组螺旋取数

    import java.util.ArrayList; import java.util.List; /** * Given a matrix of m x n elements (m rows, n ...

随机推荐

  1. ServletFileUpload 图片上传

    <script type="text/javascript"> $(function () { $('#uploadSubmit').click(function () ...

  2. [树莓派(raspberry pi)] 01、在linux环境下给树莓派安装系统及入门各种资料

    1.预准备 进入帮助页面https://www.raspberrypi.org/help/,可以直接看到GET START WITH PASPBERRY PI,点击进入: 接下来会引导你检查配件是否齐 ...

  3. 《java.util.concurrent 包源码阅读》13 线程池系列之ThreadPoolExecutor 第三部分

    这一部分来说说线程池如何进行状态控制,即线程池的开启和关闭. 先来说说线程池的开启,这部分来看ThreadPoolExecutor构造方法: public ThreadPoolExecutor(int ...

  4. 从今天起开始记录下在freecodecamp学习的一些tip吧(所有内容都在这个随笔的评论里面记录)

    因为可能东西会很零碎 所以就放在随笔里吧 当需要在字符串中使用一个: " 或者 ' 时 可以通过在引号前面使用 反斜杠 (\) 来转义引号. var sampleStr = "Al ...

  5. MVC Code First(数据模型实例讲解)

    首先配置好web.config <connectionStrings> <add name="BookDbContext" connectionString=&q ...

  6. js的学习(window对象的使用)

    open方法: //语法:var winObj = window.open([url][,name][,options]);  //参数:url:准备在新窗口中显示那个文件.url可以为空字符串,表示 ...

  7. TFS2017持续发布中调用PowerShell启停远程应用程序

    目前团队项目中有多个Web.服务以及与大数据平台对接接口等应用,每次的发布和部署采用手工的方式进行.停止应用程序,拷贝发布包,启动应用程序,不停的循环着,并且时不时地会出现一些人为错误性问题.这种模式 ...

  8. 实践作业2:黑盒测试实践——搭建被测web系统Day 4

    1.选择合适的待测web系统 2.安装web系统运行所需工具,配置运行环境 3.成功运行web系统 4.尝试Katalon测试系统

  9. TeamTalk安装测试

    TeamTalk介绍 项目框架 TeamTalk是蘑菇街的开源项目,github维护的最后时间是2015但是仍然是一款值得学习的好项目,麻雀虽小五脏俱全,本项目涉及到多个平台.多种语言,简单关系如下图 ...

  10. hdu 1151 Air Raid DAG最小边覆盖 最大二分匹配

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1151 题目大意: 城镇之间互相有边,但都是单向的,并且不会构成环,现在派伞兵降落去遍历城镇,问最少最少 ...