[array] leetcode - 54. Spiral Matrix - Medium
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),对角线可以唯一确定一个矩阵。循环获取结果,每次循环获取当前最外层的一圈数字。
- 从左到右,matrix[si][sj,...,ej]
- 从上到下,matrix[si,...,ej][ej]
- 从右到左,matrix[ei][ej-1,...,sj]
- 从下到上,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 种情况:
- dr[0], dc[0]:行的增量为 0,列的增量为 1,对应方法 1 的情况 1
- dr[1], dc[1]:行的增量为 1,列的增量为 0,对应方法 1 的情况 2
- dr[2], dc[2]:行的增量为 0,列的增量为 -1, 对应方法 1 的情况 3
- 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
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的更多相关文章
- 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 ...
- LeetCode - 54. Spiral Matrix
54. Spiral Matrix Problem's Link ------------------------------------------------------------------- ...
- leetcode 54. Spiral Matrix 、59. Spiral Matrix II
54题是把二维数组安卓螺旋的顺序进行打印,59题是把1到n平方的数字按照螺旋的顺序进行放置 54. Spiral Matrix start表示的是每次一圈的开始,每次开始其实就是从(0,0).(1,1 ...
- Leetcode 54:Spiral Matrix 螺旋矩阵
54:Spiral Matrix 螺旋矩阵 Given a matrix of m x n elements (m rows, n columns), return all elements of t ...
- leetCode 54.Spiral Matrix(螺旋矩阵) 解题思路和方法
Spiral Matrix Given a matrix of m x n elements (m rows, n columns), return all elements of the matri ...
- LeetCode: 54. Spiral Matrix(Medium)
1. 原题链接 https://leetcode.com/problems/spiral-matrix/description/ 2. 题目要求 给定一个二维整型数组,返回其螺旋顺序列表,例如: 最后 ...
- 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 ...
- [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 ...
- [leetcode]54. Spiral Matrix二维数组螺旋取数
import java.util.ArrayList; import java.util.List; /** * Given a matrix of m x n elements (m rows, n ...
随机推荐
- (一)IDEA工具开第一个springboot应用之helloworld
(一)IDEA工具开第一个springboot应用之helloworld 一.前置知识 1.maven相关知识 2.spring注解 3.RESTful API 二.idea开发第一个springbo ...
- Android OpenGL ES 开发(一): OpenGL ES 介绍
简介OpenGL ES 谈到OpenGL ES,首先我们应该先去了解一下Android的基本架构,基本架构下图: 在这里我们可以找到Libraries里面有我们目前要接触的库,即OpenGL ES. ...
- 玲珑学院-ACM比赛1014 - Absolute Defeat
1014 - Absolute Defeat Time Limit:2s Memory Limit:64MByte Submissions:257Solved:73 DESCRIPTION Eric ...
- POJ 3061 Subsequence 尺取法 POJ 3320 Jessica's Reading Problem map+set+尺取法
Subsequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 13955 Accepted: 5896 Desc ...
- CCF-201403-1-相反数
问题描述 试题编号: 201403-1 试题名称: 相反数 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 有 N 个非零且各不相同的整数.请你编一个程序求出它们中有多少对相反 ...
- CCF-201503-3-节日
问题描述 试题编号: 201503-3 试题名称: 节日 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 有一类节日的日期并不是固定的,而是以"a月的第b个星期c&q ...
- 高质量PHP代码的50个实用技巧必备(上)
1.不要使用相对路径 常常会看到: ? 1 require_once('../../lib/some_class.php'); 该方法有很多缺点: 它首先查找指定的php包含路径, 然后查找当前目录. ...
- [设计模式]PHP设计模式之单例模式
面试最常见的问题之一就是 请问您知道哪些设计模式这次先介绍最经典的单例模式.单例模式分3种:懒汉式单例.饿汉式单例.登记式单例.单例模式有以下3个特点:1.只能有一个实例.2.必须自行创建这个实例. ...
- spring mvc 复杂参数注入
过了这么久,又重新把博客拾起来了 来上海工作也已经有将近两周的时间了, 今天在整理项目的时候,遇到了一个关于参数注入的问题 背景: 我的开发前台用的是extjs4,在对后台spring mvc提交表单 ...
- Shell 初步学习
Shell 概述 Shell:Linux命令解释器 脚本执行方式 chmod 755 脚本名:赋权限(调用必须显示的使用绝对路径或相对路径) bash 脚本名:通过Bash调用执行脚本 命令别名 al ...