剑指 Offer 29. 顺时针打印矩阵
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
这题按着顺时针循环就可以,需注意索引是否越界,是否转弯处多读或少读。
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
if not matrix: return [] # 不是None
i, j, row, col =0, 0, len(matrix)-1, len(matrix[0])-1
l, r = i, j
res = []
while i<=row and j<=col:
while r<col: # 右上角留给向下移动时读
res.append(matrix[l][r])
r += 1
while l<=row: # 循环结束时 l已越界 后面需-1
res.append(matrix[l][r])
l += 1
if row>i and col>j:
r -= 1 # 从右下角的左边一个开始 需-1
l -= 1
while r>j: # 左下角留给向上移动时读
res.append(matrix[l][r])
r -= 1
while l>=i+1: # 只读到左上角的下一个
res.append(matrix[l][r])
l -= 1
l += 1 #循环结束时 l已越界 后面需+1
r += 1 #下一步循环的开始点
i, j, row, col = i+1, j+1, row-1, col-1 #四周减少一个圈
return res
官方题解:每次单一方向移动,都会改变边界。我是走完一个圈再缩小边界
if t > b: break 即等于时不结束
if l > r: break
class Solution:
def spiralOrder(self, matrix:[[int]]) -> [int]:
if not matrix: return []
l, r, t, b, res = 0, len(matrix[0]) - 1, 0, len(matrix) - 1, []
while True:
for i in range(l, r + 1): res.append(matrix[t][i]) # left to right
t += 1 # 向下移作为开始
if t > b: break
for i in range(t, b + 1): res.append(matrix[i][r]) # top to bottom
r -= 1 # 向左移作为开始
if l > r: break
for i in range(r, l - 1, -1): res.append(matrix[b][i]) # right to left
b -= 1 # 向上移作为开始
if t > b: break
for i in range(b, t - 1, -1): res.append(matrix[i][l]) # bottom to top
l += 1 # 向右移作为开始
if l > r: break
return res
剑指 Offer 31. 栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。
笔试题转成代码题:
按顺序入栈的序列,任意元素 e ,比 e 先入栈的元素,并且比 e 后出栈的元素,一定是逆序的。
想着直接观察序列,但是有点复杂。只能参考答案——模拟入栈出栈。
class Solution:
def validateStackSequences(self, pushed: List[int], popped: List[int]) -> bool:
stack, i = [], 0
for num in pushed: # 以入栈为循环次数,如果入栈完毕,列表倒序应该与出栈序列一致
stack.append(num) # num 入栈
while stack and stack[-1] == popped[i]: # 循环判断与出栈
stack.pop() #往左走
i += 1 # 往右走
return not stack