54. 螺旋矩阵(JavaScript)

给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。

示例 1:

输入:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]

示例 2:

输入:
[
  [1, 2, 3, 4],
  [5, 6, 7, 8],
  [9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]

思路:

方法一:

设置一个标志矩阵,大小与原矩阵相同,初始时的元素均为1,代表相同位置上的原矩阵元素未被访问,0代表已被访问。

设置方向变量direction,0、1、2、3分别代表右、下、左、上四个方向。

设置结果数组result = [ ].

遍历标志矩阵:当前tag位存在且为1时,将此元素加入结果数组,并将tag为置为0,并判断此时的方向:

1、方向为0(右),若右边的元素不存在,或已被访问,则改变方向为1(下),否则继续向右移动一格

2、方向为1(下),若下边的元素不存在,或已被访问,则改变方向为2(左),否则继续向下移动

3、方向为2(左),若左边的元素不存在,或已被访问,则改变方向为3(上),否则继续向左移动

4、方向为3(上),若上边的元素不存在,或已被访问,则改变方向为0(右),否则继续向上移动

/**
 * @param {number[][]} matrix
 * @return {number[]}
 */
var spiralOrder = function(matrix) {
  if (matrix.length === 0) return []
  let tag = [],
      row = matrix.length,
      col = matrix[0].length,
      direction = 0,  // 0右,1下,2左,3上
      result = []
  for (let i = 0; i < row; i++) {
    tag[i] = [];
    for (let j = 0; j < col; j++) {
      tag[i][j] = 1;  // 1:未访问,0:已访问
    }
  }
  let r = 0,
      c = 0;
  while(tag[r] && tag[r][c] === 1) {
    result.push(matrix[r][c])
    tag[r][c] = 0
    switch(direction) {
      case 0:
        if (!tag[r][c+1]) {
          direction = 1
          r++
        } else { c++ }
        break
      case 1:
        if (tag[r+1] && tag[r+1][c]) {
          r++
        } else {
          direction = 2
          c--
        }
        break
      case 2:
        if (!tag[r][c-1]) {
          direction = 3
          r--
        } else { c-- }
        break
      case 3:
        if (!tag[r-1][c]) {
          direction = 0
          c++
        } else { r-- }
        break
    }
  }
  return result;
};

方法二:

设置四个端点——上下左右:top、bottom、left、right

当上小于等于下、左小于等于右时循环:

1、向右移动,从left到right这一行元素加入结果数组result,之后将top++,(因为最上面一行都计入了,所以top要加1)并判断此时top与bottom是否合理

2、向下移动,从top到bottom这一列元素加入result,之后将right--,并判断right是否大于l等于eft

3、向左移动,加入从right到left这一行元素,之后将bottom--,同样判断bottom是否还大于等于top

4、向上移动,加入从bottom到top这一列元素,之后将left++,同样判断left是否还小于等于right

循环中任何时候只要top大于了bottom或者left大于了right,就要跳出循环。

/**
 * @param {number[][]} matrix
 * @return {number[]}
 */
var spiralOrder = function(matrix) {
  if (matrix.length === 0) return []
  let top = 0,
      bottom = matrix.length - 1,
      left = 0,
      right = matrix[0].length - 1,
      result = [];
  while (top <= bottom && left <= right) {
    for (let j = left; j <= right; j ++) {
      result.push(matrix[top][j])
    }
    if (++top > bottom) break
    for (let i = top; i <= bottom; i++) {
      result.push(matrix[i][right])
    }
    if (--right < left) break
    for (let j = right; j >= left; j--) {
      result.push(matrix[bottom][j])
    }
    if (--bottom < top) break
    for (let i = bottom; i >= top; i--) {
      result.push(matrix[i][left])
    }
    if (++left > right) break
  }
  return result
};

 

全部评论

相关推荐

01-24 08:13
已编辑
合肥工业大学 Java
程序员牛肉:没啥问题。标准的流水线简历,但是学历好一点,所以应该是有约面的机会的。 这段时间可以考虑把自己的两个项目彻底的理一理。争取能够讲清楚每一个功能点
点赞 评论 收藏
分享
野猪不是猪🐗:这种直接口头上答应,骗面试,面完了直接拉黑,相当于给自己攒面经了(
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务