54. 螺旋矩阵
给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
思路1:设置四种case,观察到第一种case是行不变列一直在变,第二种case的列数不变行数变,以此类推。
并且可以发现规律,第一次遍历的个数等于列数,第二次遍历的个数等于行数减一,第三次等于列数减一,第四次等于行数再减一。。。
case表明是哪一种情况,0对应向右, 1对应向下,2 对应向左,3对应向上
ri, ci 表示我们当前遍历的点的位置坐标。
row, col, 用来代表这一次运动的步数。我们用它们可以组合出下一次终点的坐标。举例,若是case0向右运动,所以(ri, ci + col)就是运动末位置的后一项。注意到每次运动的步数都逐步减少,发现规律:当你移完横向运动类型的运动后,row -= 1;而竖的运动(case 1 3), col -= 1。然后每一次case结尾更新ri, ci也即此次运动的末尾坐标和下一次开始的起始坐标。
思路2:考虑好边界问题。
首先定义方向:向下表示y正方向,向右表示x正方向。我们再定义两个点,分别是左上x1,y1和右下x2,y2,这样每循环一次将x1++,y1++并且x2–,y2–。
对于top箭头,采用[x1,x2]这个区间。对于right这个箭头,采用(y1,y2]这个区间。对于down这个箭头,采用(x2,x1)这个区间(注意,这里的区间定义和数学上有区别)。对于left这个箭头,采用[y2,y1)这个区间。对于循环的结束条件,定义为x1<=x2 and y1<=y2,但是这个时候要单独考虑(x2,x1)这个区间,要限定x1<x2 and y1<y2。对于[y2,y1)这个区间也要做相同的限定x1<x2,为什么呢?因为当x1==x2的时候实际上只有一列要输出,而在right中已经输出了,所以此时没有必要在此输出。
class Solution:
def spiralOrder(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: List[int]
"""
def cyc(row, column, ri, ci, case):
#递归终止条件
if row == 0 or column == 0:
return
#第一种case,横着走
if case == 0:
#结束的位置的column
endci = ci + column
for i in range(ci, endci):
#添加元素
re.append(matrix[ri][i])
#横移后row的长度减一
row -= 1
ri += 1
ci = endci-1
#我们想让case 不断增加但在0-4内循环
case = (case + 1)%4
cyc(row, column, ri, ci, case)
elif case == 1:
endri = ri + row
for i in range(ri, endri):
re.append(matrix[i][ci])
column -= 1
ci -= 1
ri = endri-1
case = (case+1)%4
cyc(row, column, ri, ci, case)
elif case == 2:
endci = ci - column
for i in range(ci, endci, -1):
re.append(matrix[ri][i])
row -= 1
ri = ri - 1
ci = endci + 1
case = (case+1)%4
cyc(row, column, ri, ci, case)
elif case == 3:
endri = ri - row
for i in range(ri, endri, -1):
re.append(matrix[i][ci])
column -= 1
ri = endri + 1
ci = ci + 1
case = (case+1)%4
cyc(row, column, ri, ci, case)
re = []
row = len(matrix)
if row == 0:
return []
column = len(matrix[0])
cyc(row, column, 0, 0, 0)
return re
class Solution:
def spiralOrder(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: List[int]
"""
result = list()
if not matrix:
return result
r, c = len(matrix), len(matrix[0])
x1, y1, x2, y2 = 0, 0, c-1, r-1
while x1 <= x2 and y1 <= y2:
for i in range(x1, x2+1):
result.append(matrix[y1][i])
for j in range(y1+1, y2+1):
result.append(matrix[j][x2])
if x1 < x2 and y1 < y2:
for i in range(x2-1, x1, -1):
result.append(matrix[y2][i])
for j in range(y2, y1, -1):
result.append(matrix[j][x1])
x1 += 1
y1 += 1
x2 -= 1
y2 -= 1
return result
59. 螺旋矩阵 II
给定一个正整数 n,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
class Solution:
def generateMatrix(self, n):
"""
:type n: int
:rtype: List[List[int]]
"""
result = [[0]*n for _ in range(n)]
x1, y1, x2, y2, k = 0, 0, n-1, n-1, 1
while x1 <= x2 and y1 <= y2:
for i in range(x1, x2+1):
result[y1][i] = k
k += 1
for j in range(y1+1, y2+1):
result[j][x2] = k
k += 1
if x1 < x2 and y1 < y2:
for i in range(x2-1, x1, -1):
result[y2][i] = k
k += 1
for j in range(y2, y1, -1):
result[j][x1] = k
k += 1
x1 += 1
y1 += 1
x2 -= 1
y2 -= 1
return result
通过顺时针的操作将数都填到数组中。
class Solution:
def generateMatrix(self, n):
"""
:type n: int
:rtype: List[List[int]]
"""
A = [[0]*n for _ in range(n)]
i, j, di, dj = 0, 0, 0, 1
for k in range(1,n**2+1):
A[i][j] = k
if A[(i+di)%n][(j+dj)%n]:
di, dj = dj, -di
i += di
j += dj
return A
61. 旋转链表
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
class Solution:
def rotateRight(self, head, k):
"""
:type head: ListNode
:type k: int
:rtype: ListNode
"""
if head == None or head.next == None:
return head
pre = head
count = 1
while pre.next != None:
count += 1
pre = pre.next
pre.next = head
n = count - k%count
q = pre
for _ in range(n):
q = q.next
ret = q.next
q.next = None
return ret