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的时候 就完全不会扫到它。

  1. public List<Integer> spiralOrder1(int[][] matrix) {
  2. List<Integer> ret = new ArrayList<Integer>();
  3. if (matrix == null || matrix.length == 0
  4. || matrix[0].length == 0) {
  5. return ret;
  6. }
  7.  
  8. rec(matrix, 0, 0, matrix.length, matrix[0].length, ret);
  9.  
  10. return ret;
  11. }
  12.  
  13. public static void rec(int[][] matrix, int x, int y, int rows, int cols, List<Integer> ret) {
  14. if (rows <= 0 || cols <= 0) {
  15. return;
  16. }
  17.  
  18. // first line
  19. for (int i = 0; i < cols; i++) {
  20. ret.add(matrix[x][y + i]);
  21. }
  22.  
  23. // right column
  24. for (int i = 1; i < rows - 1; i++) {
  25. ret.add(matrix[x + i][y + cols - 1]);
  26. }
  27.  
  28. // down row
  29. if (rows > 1) {
  30. for (int i = cols - 1; i >= 0; i--) {
  31. ret.add(matrix[x + rows - 1][y + i]);
  32. }
  33. }
  34.  
  35. // left column. GO UP.
  36. if (cols > 1) {
  37. for (int i = rows - 2; i > 0; i--) {
  38. ret.add(matrix[x + i][y]);
  39. }
  40. }
  41.  
  42. rec (matrix, x + 1, y + 1, rows - 2, cols - 2, ret);
  43. }

Solution 2:

http://blog.csdn.net/fightforyourdream/article/details/16876107?reload

感谢以上文章作者提供的思路,我们可以用x1,y1记录左上角,x2,y2记录右下角,这样子我们算各种边界值会方便好多。也不容易出错。

  1. /*
  2. Solution 2:
  3. REF: http://blog.csdn.net/fightforyourdream/article/details/16876107?reload
  4. 此算法比较不容易算错
  5. */
  6. public List<Integer> spiralOrder2(int[][] matrix) {
  7. List<Integer> ret = new ArrayList<Integer>();
  8. if (matrix == null || matrix.length == 0
  9. || matrix[0].length == 0) {
  10. return ret;
  11. }
  12.  
  13. int x1 = 0;
  14. int y1 = 0;
  15.  
  16. int rows = matrix.length;
  17. int cols = matrix[0].length;
  18.  
  19. while (rows >= 1 && cols >= 1) {
  20. // Record the right down corner of the matrix.
  21. int x2 = x1 + rows - 1;
  22. int y2 = y1 + cols - 1;
  23.  
  24. // go through the WHOLE first line.
  25. for (int i = y1; i <= y2; i++) {
  26. ret.add(matrix[x1][i]);
  27. }
  28.  
  29. // go through the right column.
  30. for (int i = x1 + 1; i < x2; i++) {
  31. ret.add(matrix[i][y2]);
  32. }
  33.  
  34. // go through the WHOLE last row.
  35. if (rows > 1) {
  36. for (int i = y2; i >= y1; i--) {
  37. ret.add(matrix[x2][i]);
  38. }
  39. }
  40.  
  41. // the left column.
  42. if (cols > 1) {
  43. for (int i = x2 - 1; i > x1; i--) {
  44. ret.add(matrix[i][y1]);
  45. }
  46. }
  47.  
  48. // in one loop we deal with 2 rows and 2 cols.
  49. rows -= 2;
  50. cols -= 2;
  51. x1++;
  52. y1++;
  53. }
  54.  
  55. return ret;
  56. }

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};

这种方向矩阵将会很常用在各种旋转数组上。

  1. /*
  2. Solution 3:
  3. 使用方向矩阵来求解
  4. */
  5.  
  6. public List<Integer> spiralOrder(int[][] matrix) {
  7. List<Integer> ret = new ArrayList<Integer>();
  8. if (matrix == null || matrix.length == 0
  9. || matrix[0].length == 0) {
  10. return ret;
  11. }
  12.  
  13. int rows = matrix.length;
  14. int cols = matrix[0].length;
  15.  
  16. int visitedRows = 0;
  17. int visitedCols = 0;
  18.  
  19. // indicate the direction of x
  20.  
  21. // 1: means we are visiting the row by the right direction.
  22. // -1: means we are visiting the row by the left direction.
  23. int[] x = {1, 0, -1, 0};
  24.  
  25. // 1: means we are visiting the colum by the down direction.
  26. // -1: means we are visiting the colum by the up direction.
  27. int[] y = {0, 1, 0, -1};
  28.  
  29. // 0: right, 1: down, 2: left, 3: up.
  30. int direct = 0;
  31.  
  32. int startx = 0;
  33. int starty = 0;
  34.  
  35. int candidateNum = 0;
  36. int step = 0;
  37. while (true) {
  38. if (x[direct] == 0) {
  39. // visit Y axis.
  40. candidateNum = rows - visitedRows;
  41. } else {
  42. // visit X axis
  43. candidateNum = cols - visitedCols;
  44. }
  45.  
  46. if (candidateNum <= 0) {
  47. break;
  48. }
  49.  
  50. ret.add(matrix[startx][starty]);
  51. step++;
  52.  
  53. if (step == candidateNum) {
  54. step = 0;
  55. visitedRows += x[direct] == 0 ? 0: 1;
  56. visitedCols += y[direct] == 0 ? 0: 1;
  57.  
  58. // move forward the direction.
  59. direct ++;
  60. direct = direct%4;
  61. }
  62.  
  63. // 根据方向来移动横坐标和纵坐标。
  64. startx += y[direct];
  65. starty += x[direct];
  66. }
  67.  
  68. return ret;
  69. }

SOLUTION 4 (December 2nd 更新):

对solution 2改进了一下,使用top,bottom,right,left记录四个角。程序更简洁漂亮。

  1. public class Solution {
  2. public List<Integer> spiralOrder(int[][] matrix) {
  3. List<Integer> ret = new ArrayList<Integer>();
  4. if (matrix == null ||matrix.length == 0) {
  5. // 注意在非法的时候,应该返回空解,而不是一个NULL值
  6. return ret;
  7. }
  8.  
  9. // Record how many rows and cols we still have.
  10. int rows = matrix.length;
  11. int cols = matrix[0].length;
  12.  
  13. // The four coners.
  14. int top = 0;
  15. int left = 0;
  16. int bottom = rows - 1;
  17. int right = cols - 1;
  18.  
  19. // every time we go through two rows and two cols.
  20. for (; rows > 0 && cols > 0; rows -= 2, cols -= 2, top++, left++, bottom--, right--) {
  21. // the first line.
  22. for (int i = left; i <= right; i++) {
  23. ret.add(matrix[top][i]);
  24. }
  25.  
  26. // the right column.
  27. for (int i = top + 1; i < bottom; i++) {
  28. ret.add(matrix[i][right]);
  29. }
  30.  
  31. // the down line;
  32. if (rows > 1) {
  33. for (int j = right; j >= left; j--) {
  34. ret.add(matrix[bottom][j]);
  35. }
  36. }
  37.  
  38. // the left column.
  39. if (cols > 1) {
  40. for (int i = bottom - 1; i > top; i --) {
  41. ret.add(matrix[i][left]);
  42. }
  43. }
  44. }
  45.  
  46. return ret;
  47. }
  48. }

2015.1.9 redo:

可以不用rows/cols来记录行列数。只需要判断四个边界是否相撞即可。

  1. public List<Integer> spiralOrder3(int[][] matrix) {
  2. List<Integer> ret = new ArrayList<Integer>();
  3. if (matrix == null || matrix.length == || matrix[].length == ) {
  4. return ret;
  5. }
  6.  
  7. int rows = matrix.length;
  8. int cols = matrix[].length;
  9.  
  10. int left = ;
  11. int right = cols - ;
  12. int top = ;
  13. int bottom = rows - ;
  14.  
  15. while (left <= right && top <= bottom) {
  16. // line top.
  17. for (int i = left; i <= right; i++) {
  18. ret.add(matrix[top][i]);
  19. }
  20.  
  21. // line right;
  22. for (int i = top + ; i <= bottom - ; i++) {
  23. ret.add(matrix[i][right]);
  24. }
  25.  
  26. // line bottom.
  27. if (top != bottom) {
  28. for (int i = right; i >= left; i--) {
  29. ret.add(matrix[bottom][i]);
  30. }
  31. }
  32.  
  33. // line left;
  34. if (left != right) {
  35. for (int i = bottom - ; i >= top + ; i--) {
  36. ret.add(matrix[i][left]);
  37. }
  38. }
  39.  
  40. left++;
  41. right--;
  42. top++;
  43. bottom--;
  44. }
  45.  
  46. return ret;
  47. }

GitHub CODE:

spiralOrder.java

LeetCode: Spiral Matrix 解题报告的更多相关文章

  1. 【LeetCode】54. Spiral Matrix 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 维护四个边界和运动方向 保存已经走过的位置 日期 题 ...

  2. LeetCode: Spiral Matrix II 解题报告-三种方法解决旋转矩阵问题

    Spiral Matrix IIGiven an integer n, generate a square matrix filled with elements from 1 to n2 in sp ...

  3. 【LeetCode】01 Matrix 解题报告

    [LeetCode]01 Matrix 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/01-matrix/#/descripti ...

  4. 【LeetCode】378. Kth Smallest Element in a Sorted Matrix 解题报告(Python)

    [LeetCode]378. Kth Smallest Element in a Sorted Matrix 解题报告(Python) 标签: LeetCode 题目地址:https://leetco ...

  5. LeetCode: Combination Sum 解题报告

    Combination Sum Combination Sum Total Accepted: 25850 Total Submissions: 96391 My Submissions Questi ...

  6. [LeetCode] Spiral Matrix II 螺旋矩阵之二

    Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For ...

  7. [LeetCode] 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】Permutations 解题报告

    全排列问题.经常使用的排列生成算法有序数法.字典序法.换位法(Johnson(Johnson-Trotter).轮转法以及Shift cursor cursor* (Gao & Wang)法. ...

  9. LeetCode - Course Schedule 解题报告

    以前从来没有写过解题报告,只是看到大肥羊河delta写过不少.最近想把写博客的节奏给带起来,所以就挑一个比较容易的题目练练手. 原题链接 https://leetcode.com/problems/c ...

随机推荐

  1. [Python]项目打包:5步将py文件打包成exe文件 简介

    1.下载pyinstaller并解压(可以去官网下载最新版): http://nchc.dl.sourceforge.net/project/pyinstaller/2.0/pyinstaller-2 ...

  2. github下载源码的三种方式

      从github上下载源码的三种方式 CreationTime--2018年6月7日15点21分 Author:Marydon 1.情景展示 2.实现方式 方式一:直接点击"Downloa ...

  3. eclipse查看源码失败总结

    之前看的网上查看源码的方法,查看了JDK,只是知其然不知所以然. 后来发现要是查看其他源码,总是查看失败. 最开始每次点击Attach  Source包到所要查看源码的jar包,但是还是这样. 但是依 ...

  4. CitrixSmartAuditor安装报错解决方法

    报错1:安装过程中报错 解决方法: SQLServer的配置: http://www.cnblogs.com/weizhengLoveMayDay/p/3267756.html 报错2:无法连接到Sm ...

  5. 如何解决普通用户使用sudo找不到命令

    一.在linux的普通用户下,要使用root权限的命令需要使用sudo [dev@dev1 client_api]# sudo git pull origin develop sudo: git: c ...

  6. Python中 append 和 extend 的区别

    Python中Lists 的两个方法: append 和 extend : list.append(object) 向列表中添加一个对象object.append 接受一个参数,这个参数可以是任何数据 ...

  7. JQuery中event的preventDefault和stopPropagation介绍

    event.preventDefault()阻止默认事件行为的触发. event.stopPropagation()防止事件冒泡到DOM树上,也就是不触发的任何前辈元素上的事件处理函数. <!D ...

  8. RMAN - 发现I/O瓶颈

    大多数操作系统支持异步I/O. 备份到磁盘,异步I/O是一个优势,因为一个服务器进程同时可以执行多个I/O操作:同步I/O必须等上一个I/O操作完成才可以执行下一个I/O操作. 初始化参数disk_a ...

  9. Python rindex() 方法

    描述 Python rindex() 方法返回子字符串最后一次出现在字符串中的索引位置,该方法与rfind() 方法一样,只不过如果子字符串不在字符串中会报一个异常. 语法 rindex() 方法语法 ...

  10. Aixs2 使用总结,持续更新中 ...

    参考博客:http://zhangjunhd.blog.51cto.com/113473/23692     消息交换模式. 目前Axis2支持三种模式:In-Only.Robust-In和In-Ou ...