LeetCode: Spiral Matrix 解题报告
Spiral Matrix
Given 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].
Solution 1:
使用递归,一次扫描一整圈,然后用x,y记录这个圈的左上角,递归完了都+1。rows, cols记录还没扫的有多少。思想比较简单,但相当容易出错。起码提交了5次才最后过。
注意:1. 扫描第一行跟最后一行要扫到底部为止,而扫描左列和右列只需要扫中间的。
1 2 3 4
5 6 7 8
9 10 11 12
例如以上例子: 你要 先扫1234, 然后是8,然后是12 11 10 9 然后是 5.
不能这样:123, 4 8, 12 11 10 , 9 5。 用后者的方法在只有一个数字 1的时候 就完全不会扫到它。
- public List<Integer> spiralOrder1(int[][] matrix) {
- List<Integer> ret = new ArrayList<Integer>();
- if (matrix == null || matrix.length == 0
- || matrix[0].length == 0) {
- return ret;
- }
- rec(matrix, 0, 0, matrix.length, matrix[0].length, ret);
- return ret;
- }
- public static void rec(int[][] matrix, int x, int y, int rows, int cols, List<Integer> ret) {
- if (rows <= 0 || cols <= 0) {
- return;
- }
- // first line
- for (int i = 0; i < cols; i++) {
- ret.add(matrix[x][y + i]);
- }
- // right column
- for (int i = 1; i < rows - 1; i++) {
- ret.add(matrix[x + i][y + cols - 1]);
- }
- // down row
- if (rows > 1) {
- for (int i = cols - 1; i >= 0; i--) {
- ret.add(matrix[x + rows - 1][y + i]);
- }
- }
- // left column. GO UP.
- if (cols > 1) {
- for (int i = rows - 2; i > 0; i--) {
- ret.add(matrix[x + i][y]);
- }
- }
- rec (matrix, x + 1, y + 1, rows - 2, cols - 2, ret);
- }
Solution 2:
http://blog.csdn.net/fightforyourdream/article/details/16876107?reload
感谢以上文章作者提供的思路,我们可以用x1,y1记录左上角,x2,y2记录右下角,这样子我们算各种边界值会方便好多。也不容易出错。
- /*
- Solution 2:
- REF: http://blog.csdn.net/fightforyourdream/article/details/16876107?reload
- 此算法比较不容易算错
- */
- public List<Integer> spiralOrder2(int[][] matrix) {
- List<Integer> ret = new ArrayList<Integer>();
- if (matrix == null || matrix.length == 0
- || matrix[0].length == 0) {
- return ret;
- }
- int x1 = 0;
- int y1 = 0;
- int rows = matrix.length;
- int cols = matrix[0].length;
- while (rows >= 1 && cols >= 1) {
- // Record the right down corner of the matrix.
- int x2 = x1 + rows - 1;
- int y2 = y1 + cols - 1;
- // go through the WHOLE first line.
- for (int i = y1; i <= y2; i++) {
- ret.add(matrix[x1][i]);
- }
- // go through the right column.
- for (int i = x1 + 1; i < x2; i++) {
- ret.add(matrix[i][y2]);
- }
- // go through the WHOLE last row.
- if (rows > 1) {
- for (int i = y2; i >= y1; i--) {
- ret.add(matrix[x2][i]);
- }
- }
- // the left column.
- if (cols > 1) {
- for (int i = x2 - 1; i > x1; i--) {
- ret.add(matrix[i][y1]);
- }
- }
- // in one loop we deal with 2 rows and 2 cols.
- rows -= 2;
- cols -= 2;
- x1++;
- y1++;
- }
- return ret;
- }
Solution 3:
http://fisherlei.blogspot.com/2013/01/leetcode-spiral-matrix.html
感谢水中的鱼大神。这是一种相当巧妙的思路,我们这次可以用Iterator来实现了,记录2个方向数组,分别表示在x方向,y方向的前进方向。1表示右或是下,-1表示左或是向上,0表示不动作。
// 1: means we are visiting the row by the right direction.
// -1: means we are visiting the row by the left direction.
int[] x = {1, 0, -1, 0};
// 1: means we are visiting the colum by the down direction.
// -1: means we are visiting the colum by the up direction.
int[] y = {0, 1, 0, -1};
这种方向矩阵将会很常用在各种旋转数组上。
- /*
- Solution 3:
- 使用方向矩阵来求解
- */
- public List<Integer> spiralOrder(int[][] matrix) {
- List<Integer> ret = new ArrayList<Integer>();
- if (matrix == null || matrix.length == 0
- || matrix[0].length == 0) {
- return ret;
- }
- int rows = matrix.length;
- int cols = matrix[0].length;
- int visitedRows = 0;
- int visitedCols = 0;
- // indicate the direction of x
- // 1: means we are visiting the row by the right direction.
- // -1: means we are visiting the row by the left direction.
- int[] x = {1, 0, -1, 0};
- // 1: means we are visiting the colum by the down direction.
- // -1: means we are visiting the colum by the up direction.
- int[] y = {0, 1, 0, -1};
- // 0: right, 1: down, 2: left, 3: up.
- int direct = 0;
- int startx = 0;
- int starty = 0;
- int candidateNum = 0;
- int step = 0;
- while (true) {
- if (x[direct] == 0) {
- // visit Y axis.
- candidateNum = rows - visitedRows;
- } else {
- // visit X axis
- candidateNum = cols - visitedCols;
- }
- if (candidateNum <= 0) {
- break;
- }
- ret.add(matrix[startx][starty]);
- step++;
- if (step == candidateNum) {
- step = 0;
- visitedRows += x[direct] == 0 ? 0: 1;
- visitedCols += y[direct] == 0 ? 0: 1;
- // move forward the direction.
- direct ++;
- direct = direct%4;
- }
- // 根据方向来移动横坐标和纵坐标。
- startx += y[direct];
- starty += x[direct];
- }
- return ret;
- }
SOLUTION 4 (December 2nd 更新):
对solution 2改进了一下,使用top,bottom,right,left记录四个角。程序更简洁漂亮。
- public class Solution {
- public List<Integer> spiralOrder(int[][] matrix) {
- List<Integer> ret = new ArrayList<Integer>();
- if (matrix == null ||matrix.length == 0) {
- // 注意在非法的时候,应该返回空解,而不是一个NULL值
- return ret;
- }
- // Record how many rows and cols we still have.
- int rows = matrix.length;
- int cols = matrix[0].length;
- // The four coners.
- int top = 0;
- int left = 0;
- int bottom = rows - 1;
- int right = cols - 1;
- // every time we go through two rows and two cols.
- for (; rows > 0 && cols > 0; rows -= 2, cols -= 2, top++, left++, bottom--, right--) {
- // the first line.
- for (int i = left; i <= right; i++) {
- ret.add(matrix[top][i]);
- }
- // the right column.
- for (int i = top + 1; i < bottom; i++) {
- ret.add(matrix[i][right]);
- }
- // the down line;
- if (rows > 1) {
- for (int j = right; j >= left; j--) {
- ret.add(matrix[bottom][j]);
- }
- }
- // the left column.
- if (cols > 1) {
- for (int i = bottom - 1; i > top; i --) {
- ret.add(matrix[i][left]);
- }
- }
- }
- return ret;
- }
- }
2015.1.9 redo:
可以不用rows/cols来记录行列数。只需要判断四个边界是否相撞即可。
- public List<Integer> spiralOrder3(int[][] matrix) {
- List<Integer> ret = new ArrayList<Integer>();
- if (matrix == null || matrix.length == || matrix[].length == ) {
- return ret;
- }
- int rows = matrix.length;
- int cols = matrix[].length;
- int left = ;
- int right = cols - ;
- int top = ;
- int bottom = rows - ;
- while (left <= right && top <= bottom) {
- // line top.
- for (int i = left; i <= right; i++) {
- ret.add(matrix[top][i]);
- }
- // line right;
- for (int i = top + ; i <= bottom - ; i++) {
- ret.add(matrix[i][right]);
- }
- // line bottom.
- if (top != bottom) {
- for (int i = right; i >= left; i--) {
- ret.add(matrix[bottom][i]);
- }
- }
- // line left;
- if (left != right) {
- for (int i = bottom - ; i >= top + ; i--) {
- ret.add(matrix[i][left]);
- }
- }
- left++;
- right--;
- top++;
- bottom--;
- }
- return ret;
- }
GitHub CODE:
LeetCode: Spiral Matrix 解题报告的更多相关文章
- 【LeetCode】54. Spiral Matrix 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 维护四个边界和运动方向 保存已经走过的位置 日期 题 ...
- LeetCode: Spiral Matrix II 解题报告-三种方法解决旋转矩阵问题
Spiral Matrix IIGiven an integer n, generate a square matrix filled with elements from 1 to n2 in sp ...
- 【LeetCode】01 Matrix 解题报告
[LeetCode]01 Matrix 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/01-matrix/#/descripti ...
- 【LeetCode】378. Kth Smallest Element in a Sorted Matrix 解题报告(Python)
[LeetCode]378. Kth Smallest Element in a Sorted Matrix 解题报告(Python) 标签: LeetCode 题目地址:https://leetco ...
- LeetCode: Combination Sum 解题报告
Combination Sum Combination Sum Total Accepted: 25850 Total Submissions: 96391 My Submissions Questi ...
- [LeetCode] Spiral Matrix II 螺旋矩阵之二
Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For ...
- [LeetCode] Spiral Matrix 螺旋矩阵
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral or ...
- 【LeetCode】Permutations 解题报告
全排列问题.经常使用的排列生成算法有序数法.字典序法.换位法(Johnson(Johnson-Trotter).轮转法以及Shift cursor cursor* (Gao & Wang)法. ...
- LeetCode - Course Schedule 解题报告
以前从来没有写过解题报告,只是看到大肥羊河delta写过不少.最近想把写博客的节奏给带起来,所以就挑一个比较容易的题目练练手. 原题链接 https://leetcode.com/problems/c ...
随机推荐
- [Python]项目打包:5步将py文件打包成exe文件 简介
1.下载pyinstaller并解压(可以去官网下载最新版): http://nchc.dl.sourceforge.net/project/pyinstaller/2.0/pyinstaller-2 ...
- github下载源码的三种方式
从github上下载源码的三种方式 CreationTime--2018年6月7日15点21分 Author:Marydon 1.情景展示 2.实现方式 方式一:直接点击"Downloa ...
- eclipse查看源码失败总结
之前看的网上查看源码的方法,查看了JDK,只是知其然不知所以然. 后来发现要是查看其他源码,总是查看失败. 最开始每次点击Attach Source包到所要查看源码的jar包,但是还是这样. 但是依 ...
- CitrixSmartAuditor安装报错解决方法
报错1:安装过程中报错 解决方法: SQLServer的配置: http://www.cnblogs.com/weizhengLoveMayDay/p/3267756.html 报错2:无法连接到Sm ...
- 如何解决普通用户使用sudo找不到命令
一.在linux的普通用户下,要使用root权限的命令需要使用sudo [dev@dev1 client_api]# sudo git pull origin develop sudo: git: c ...
- Python中 append 和 extend 的区别
Python中Lists 的两个方法: append 和 extend : list.append(object) 向列表中添加一个对象object.append 接受一个参数,这个参数可以是任何数据 ...
- JQuery中event的preventDefault和stopPropagation介绍
event.preventDefault()阻止默认事件行为的触发. event.stopPropagation()防止事件冒泡到DOM树上,也就是不触发的任何前辈元素上的事件处理函数. <!D ...
- RMAN - 发现I/O瓶颈
大多数操作系统支持异步I/O. 备份到磁盘,异步I/O是一个优势,因为一个服务器进程同时可以执行多个I/O操作:同步I/O必须等上一个I/O操作完成才可以执行下一个I/O操作. 初始化参数disk_a ...
- Python rindex() 方法
描述 Python rindex() 方法返回子字符串最后一次出现在字符串中的索引位置,该方法与rfind() 方法一样,只不过如果子字符串不在字符串中会报一个异常. 语法 rindex() 方法语法 ...
- Aixs2 使用总结,持续更新中 ...
参考博客:http://zhangjunhd.blog.51cto.com/113473/23692 消息交换模式. 目前Axis2支持三种模式:In-Only.Robust-In和In-Ou ...