我在解决以下问题中的奇数输入情况时遇到问题:给定m×n个元素的矩阵(m行,n列),以螺旋顺序返回矩阵的所有元素。
For example,
Given the following matrix:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
You should return [1,2,3,6,9,8,7,4,5].
我的代码适用于所有更大的测试用例,但对于像
这样的事情却失败了[[6,9,7]]
我不知道如何构建我的代码来处理这些输入。有人有想法吗?
def spiral_order(matrix)
return nil if matrix.nil?
return [] if matrix.empty?
m = matrix.length - 1
n = matrix.first.length - 1
start_col = start_row = 0
end_col = n
end_row = m
visited = []
iter = 0
until start_row > end_row && start_col > end_col
until iter > end_col
visited << matrix[start_row][iter]
iter+=1
end
start_row += 1
iter = start_row
until iter > end_row
visited << matrix[iter][end_col]
iter += 1
end
end_col -= 1
iter = end_col
until iter < start_col
visited << matrix[end_row][iter]
iter-=1
end
end_row -= 1
iter = end_row
until iter < start_row
visited << matrix[iter][start_col]
iter -= 1
end
start_col += 1
iter = start_col
end
visited
end
在[6,9,7]上我在第17行得到一个nil错误。我知道整个循环运行两次(这本身不应该是这种情况,因为我正在增加启动限制并递减最终限制)但我正在努力创建适用于常规输入和奇怪情况的代码,而不需要投入大量条件来处理更多不寻常的情况。
答案 0 :(得分:-1)
这可以使用更简单的代码集来解决。从矩阵中剥离顶行,旋转矩阵,重复直到空。
def spiral_order(matrix)
m = matrix.dup
result = []
until m.size < 1
result << m.shift
m = m.transpose.reverse
end
result.flatten
end
>> matrix = [[1,2,3],[4,5,6],[7,8,9]]
>> spiral_order(matrix)
=> [1, 2, 3, 6, 9, 8, 7, 4, 5]
>> matrix = [[6,9,7]]
>> spiral_order(matrix)
=> [6, 9, 7]
如果您正在处理大型矩阵并希望避免多次重复,那么为了增加一些复杂性,您可以这样做:
def spiral_order(matrix)
m = matrix.map(&:dup)
result = []
until m.size < 1
result << m.shift
result << m.map(&:pop)
result << (m.pop || []).reverse
result << m.map(&:shift).reverse
end
result.flatten.compact
end
算法的工作原理如下:第2行深度复制矩阵,因此传入的原始内容不受影响。第5行剥离顶行。第6行剥离右列。第7行剥离底行并反转它。 (|| []
确保我们不会在零值上调用#reverse
。)第8行剥离左列并将其反转。重复第5-8行直到矩阵为空。此时,第10行删除内部数组和nils并返回结果。