Leecode 54. 螺旋矩阵

题目

给定一个包含 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]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/spiral-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
复制代码

先大体感觉一下,是一个有意思的二维数组遍历,不过时顺时针的。

在一个矩阵上顺时针旋转的话,一共有四个方向,即 右(1,0),下(0,1),左(-1,0),上(0,-1)。每当接触到一个边界之后,进行方向的改变。

然后先确定四个边界点,左上,右上,右下,左下,在这个例子中,即为(0,0),(2,0),(2,2),(0,2)

当接触到一个边界,在改变方向的同时,也应该缩小边界点的位置。

比如说 右,接触到了边界,此时应该方向应转为下,对应的上边界应该 y+1
比如说 下,接触到了边界,此时应该方向应转为左,对应的右边界应该 x-1
以此类推
复制代码

开始按照一个方向进行前进,每当越界的时候,进行方向的矫正。并检查是否遍历完成,这里遍历完成的检查比较简单。即,检查左上的 x y 是否比 右下的 x y 要大。如果同时满足这两点,那么遍历结束。

最后的结果

class Solution:
    class Point:
        def __init__(self, x, y):
            self.x = x
            self.y = y

        def __str__(self):
            return "Point(x:%d,y:%d)" % (self.x, self.y)
    def spiralOrder(self, matrix: [[int]]) -> [int]:
        n = len(matrix)
        if n == 0:
            return []
        m = len(matrix[0])
        ret = []
        
        currentPoint = Point(0,0)
        direction = Point(1,0)
        lt = Point(0,0)
        rt = Point(m-1,0)
        lb = Point(0, n-1)
        rb = Point(m-1,n-1)

        # print(lt,rt)
        # print(lb,rb)

        # print(matrix[currentPoint.y][currentPoint.x])
        ret.append(matrix[currentPoint.y][currentPoint.x])
        # print("%d %d : %d" % (currentPoint.y, currentPoint.x,matrix[currentPoint.y][currentPoint.x]))
        while True:
            nextP = Point(currentPoint.x+direction.x,currentPoint.y+direction.y)
            # print("%d %d %s" % (nextP.y, nextP.x, direction))
            if lt.x <= nextP.x <= rb.x and lt.y <= nextP.y <= rb.y:
                currentPoint = nextP

                # print()
                # print("%d %d : %d" % (currentPoint.y, currentPoint.x,matrix[currentPoint.y][currentPoint.x]))
                ret.append(matrix[currentPoint.y][currentPoint.x])
            else:
                if direction.x == 1 and direction.y == 0:
                    # direction = Point(0,1)
                    direction.x = 0
                    direction.y = 1
                    lt.y += 1
                    rt.y = lt.y
                elif direction.x == 0 and direction.y == 1:
                    # direction = Point(-1,0)
                    direction.x = -1
                    direction.y = 0
                    rt.x -= 1
                    rb.x = rt.x
                elif direction.x == -1 and direction.y == 0:
                    # direction = Point(0,-1)
                    direction.x = 0
                    direction.y = -1
                    lb.y -= 1
                    rb.y = lb.y
                else:
                    # direction = Point(1, 0)
                    direction.x = 1
                    direction.y = 0
                    lt.x += 1
                    lb.x = lt.x
                if lt.x > rt.x and lt.y > rb.y:
                    break
        return ret
复制代码

转载于:https://juejin.im/post/5cff55bbe51d4556d86c7aa1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值