LeetCode 054: 螺旋矩阵
Given an m x n matrix, return all elements of the matrix in spiral order.
思路一:模拟螺旋矩阵的路径。初始位置是矩阵的左上角,初始方向是向右,当路径超出界限或者进入之前访问过的位置时,则顺时针旋转,进入下一个方向。
思路二:将矩阵看成若干层,首先输出最外层的元素,其次输出次外层的元素,直到输出最内层的元素。
下面的代码是思路一的模拟螺旋矩阵的路径,因为涉及的for循环比较少,相对耗时较少。
if not matrix or not matrix[0]:
return list()
rows, columns = len(matrix), len(matrix[0])
visited = [[False] * columns for _ in range(rows)]
total = rows * columns
order = [0] * total
directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]
row, column = 0, 0
directionIndex = 0
for i in range(total):
order[i] = matrix[row][column]
visited[row][column] = True
nextRow, nextColumn = row + directions[directionIndex][0], column + directions[directionIndex][1]
if not (0 <= nextRow < rows and 0 <= nextColumn < columns and not visited[nextRow][nextColumn]):
directionIndex = (directionIndex + 1) % 4
row += directions[directionIndex][0]
column += directions[directionIndex][1]
return order
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/spiral-matrix/solution/luo-xuan-ju-zhen-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
还有一个比较取巧的解法是利用python矩阵的pop()
函数。解决方案出自LeetCode-python 54.螺旋矩阵。
class Solution(object):
def spiralOrder(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: List[int]
"""
res = []
while matrix:
res += matrix.pop(0)
if matrix and matrix[0]:
for m in matrix:
res += [m.pop()]
if matrix:
res += matrix.pop()[::-1]
t = []
if matrix and matrix[0]:
for m in matrix:
t += [m.pop(0)]
res += t[::-1]
return res
LeetCode 059: 螺旋矩阵 II
Given a positive integer n,
generate an n x n matrix filled with elements from 1 to n2 in spiral order.
一个比较短小精悍的解决方案,出自LeetCode-python 59.螺旋矩阵 II。
思路:
按数字递增的方向,坐标值变化的方式为
上:dx=0, dy=1
右:dx=1, dy=0
下:dx=0,dy=-1
左:dx=-1,dy=0
每次拐弯:
dx都变为原来的dy
dy都变为原来的-dx
拐弯的条件:
matrix[x][y]已经有值,对于最外面一圈:matrix[x%n][y%n]有值
作者:wzNote
链接:https://www.jianshu.com/p/909443f180c9
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
代码:
class Solution(object):
def generateMatrix(self, n):
"""
:type n: int
:rtype: List[List[int]]
"""
res = [[0]*n for _ in range(n)]
i, j, di, dj = 0, 0, 0, 1
for k in range(1, n*n+1):
res[i][j] = k
if res[(i+di)%n][(j+dj)%n]:
di, dj = dj, -di
i += di
j += dj
return res
还有几个不错的解决方案:
leetcode59 spiral-matrix-ii螺旋矩阵二
LeetCode59. 螺旋矩阵 II(python)
LeetCode051Spiral Matrix II (模拟法,设定边界,代码简短清晰)精选解决方案
LeetCode 061: 旋转链表
Given the head of a linked list, rotate the list to the right by k places.
思路一:绕圈
1)数节点个数
2)连接首尾节点
3)运动到新的头部节点的上一位,断开链表
4)返回新的头部节点
思路二:快慢指针
1)定义2个指针,一快一慢
2)快的先走k步,慢的不动
3)接着快慢一起动,当快的走到节点的时候,慢的的下一项就是新的头部节点。
由于第一种思路耗时比较短,这里就放它的代码。
class Solution:
def rotateRight(self, head, k):
"""
:type head: ListNode
:type k: int
:rtype: ListNode
"""
dummy = ListNode(0)
dummy.next = head
if head is None:
return None
#先数链表有几个节点
i = head
count = 1
while i.next is not None:
i = i.next
count += 1
#抛掉重复的转圈,也算一种算法优化吧
k = k%count
if (k == 0) or count == 1:
return head
#把链表头尾连起来
i.next = head
#从dummy开始运动
i = dummy
#运动到新的链表的头的上一个节点
for _ in range(count - k):
i = i.next
j = i.next
i.next = None
return j
思路和代码都出自Leetcode 061 旋转链表 python (多解法)。感兴趣的可以去原文仔细阅读。
LeetCode61旋转链表官方解决方案
任务链接:
team-learning-program/LeetCodeTencent/054 螺旋矩阵.md
team-learning-program/LeetCodeTencent/059 螺旋矩阵 II.md
team-learning-program/LeetCodeTencent/061 旋转链表.md