【LeetCode每日一题】2020.6.5 面试题29. 顺时针打印矩阵

面试题29. 顺时针打印矩阵

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

示例:

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

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

分析:

​ 可以先在草稿纸上写画一下,就可以发现迭代的结构:最上一行从左到右、最右一列从上至下、最底行从右至左、最左列从上至下。麻烦的是如何设置迭代条件,以及边界的处理。我们可以设置四个变量来控制边界,分别是left、right、top、bottom,来控制循环。

  1. 初始化:left, right, top, bottom = 0, cols - 1, 0, rows - 1

  2. 接下来是选择边界条件,画图可以分析一下:

    • 如果我们向下图一样来进行遍历:在最后一行、一列或一个元素时会不方便控制,需要单独拿出来判断

      top == bottom or left == right

    • 我们也可以像下图一样进行遍历,但这样又需要在每次循环的第三、四前进行一次判断,防止溢出:

代码(Golang):

法1:

func spiralOrder(matrix [][]int) []int {
	if len(matrix) == 0 || len(matrix[0]) == 0 {
		return []int{}
	}
	var (
		rows, cols = len(matrix), len(matrix[0])
		res = make([]int, rows * cols)
		index = 0
		left, right, top, bottom = 0, cols - 1, 0, rows - 1
	)
	for left < right && top < bottom {
		for c := left; c < right; c++ {
			res[index] = matrix[top][c]
			index++
		}
		for r := top; r < bottom; r++ {
			res[index] = matrix[r][right]
			index++
		}
        for c := right; c > left; c-- {
            res[index] = matrix[bottom][c]
            index++
        }
        for r := bottom; r > top; r-- {
            res[index] = matrix[r][left]
            index++
        }
		left++
		right--
		top++
		bottom--
	}
	if left == right {
		for r := top; r <= bottom; r++ {
			res[index] = matrix[r][left]
			index++
		}
	} else if top == bottom {
		for c := left; c <= right; c++ {
			res[index] = matrix[top][c]
			index++
		}
	}
	return res
}

法2:

func spiralOrder(matrix [][]int) []int {
   if len(matrix) == 0 || len(matrix[0]) == 0 {
      return []int{}
   }
   var (
      rows, cols = len(matrix), len(matrix[0])
      res = make([]int, rows * cols)
      index = 0
      left, right, top, bottom = 0, cols - 1, 0, rows - 1
   )
   for left <= right && top <= bottom {
      for c := left; c <= right; c++ {
         res[index] = matrix[top][c]
         index++
      }
      for r := top + 1; r <= bottom; r++ {
         res[index] = matrix[r][right]
         index++
      }
      if left < right && top < bottom {
         for c := right - 1; c > left; c-- {
            res[index] = matrix[bottom][c]
            index++
         }
         for r := bottom; r > top; r-- {
            res[index] = matrix[r][left]
            index++
         }
      }
      left++
      right--
      top++
      bottom--
   }
   return res
}

总结:

​ 这道题背后应该没有什么特殊的算法思想,当遇到这种题时,最好的方法就是画图帮助自己理解。模拟得出结果的过程,将条件判断编写清楚即可。

原文地址:https://www.cnblogs.com/enmac/p/13052736.html