• 【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
    }
    

    总结:

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

  • 相关阅读:
    c# 基本值类型及其默认值
    军史馆如何营造更好的意境
    部队营区生态环境设计与文化氛围营造
    我的第一个CAD程序
    经典SQL语句大全
    带图标和多行显示的ListBox
    CAD 二次开发 -- 自动加载开发的DLL
    Git使用总结
    OpenStack迁移虚拟机流程分析
    OpenStack创建虚拟机流程
  • 原文地址:https://www.cnblogs.com/enmac/p/13052736.html
Copyright © 2020-2023  润新知