- Spiral Matrix Medium
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
Example 1:
Input: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ] Output: [1,2,3,6,9,8,7,4,5]
Example 2:
Input: [ [1, 2, 3, 4], [5, 6, 7, 8], [9,10,11,12] ] Output: [1,2,3,4,8,12,11,10,9,5,6,7]
簡單說就是二維陣列順時針?讀取成一位陣列,拆開看問題,其實每次去掉最外面一層剩下的還是一個二維陣列,從這裡出發可以使用遞迴,但是這裡使用迴圈就夠了,加四個標誌位:上下左右,Swift(100%)程式碼如下:
// swift code
class Solution {
func spiralOrder(_ matrix: [[Int]]) -> [Int] {
// 特殊 case 直接返回
if matrix.count < 2 { return matrix.first ?? [] }
// 標記左右上下
var l = 0, r = matrix.first!.count - 1, t = 0, b = matrix.count - 1
var result = [Int]()
// 陣列片段轉置且型別轉為陣列
let reverse_: (ArraySlice<Int>) -> [Int] = { (slice) in
var temp = slice
temp.reverse()
return Array(temp)
}
while true {
// 每一組的第一行是可以直接追加到結果中的
result += Array(matrix[t][l...r])
if t + 1 < b {
// 自上至下取出每一個陣列的最後一個有效元素加入到結果
for i in (t + 1)..<b {
result.append(matrix[i][r])
}
result += reverse_(matrix[b][l...r])
if l != r {
var temp = b - 1
// 自下至上取出每一個陣列的第一個有效元素加入到結果
while temp > t {
result.append(matrix[temp][l])
temp -= 1
}
r -= 1
l += 1
t += 1
b -= 1
if l > r {
break
}
} else {
break
}
} else if t != b {
// 最後一行的轉置陣列加到結果中
result += reverse_(matrix[b][l...r])
break
} else {
break
}
}
return result
}
}
複製程式碼
TestCase
// swift code
assert(Solution().spiralOrder([[1]]) == [1])
assert(Solution().spiralOrder([[1], [2]]) == [1, 2])
assert(Solution().spiralOrder([[1], [2], [3]]) == [1, 2, 3])
assert(Solution().spiralOrder([[1, 2], [4, 5]]) == [1, 2, 5, 4])
assert(Solution().spiralOrder([[2, 5], [8, 4], [0 ,-1]]) == [2, 5, 4, -1, 0, 8])
assert(Solution().spiralOrder([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) == [1, 2, 3, 6, 9, 8, 7, 4, 5])
assert(Solution().spiralOrder([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]) == [1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7])
複製程式碼