Spiral Matrix I
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
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]
.
顺序添加法
复杂度
时间 O(NM) 空间 O(1)
思路
首先考虑最简单的情况,如图我们先找最外面这圈X,这种情况下我们是第一行找前4个,最后一列找前4个,最后一行找后4个,第一列找后4个,这里我们可以发现,第一行和最后一行,第一列和最后一列都是有对应关系的。即对i
行,其对应行是m - i - 1
,对于第j
列,其对应的最后一列是n - j - 1
。
XXXXX
XOOOX
XOOOX
XOOOX
XXXXX
然后进入到里面那一圈,同样的顺序没什么问题,然而关键在于下图这么两种情况,一圈已经没有四条边了,所以我们要单独处理,只加那唯一的一行或一列。另外,根据下图我们可以发现,圈数是宽和高中较小的那个,加1再除以2。
OOOOO OOO
OXXXO OXO
OOOOO OXO
OXO
OOO
代码
public class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> res = new LinkedList<Integer>();
if(matrix.length == 0) return res;
int m = matrix.length, n = matrix[0].length;
// 计算圈数
int lvl = (Math.min(m, n) + 1) / 2;
for(int i = 0; i < lvl; i++){
// 计算相对应的该圈最后一行
int lastRow = m - i - 1;
// 计算相对应的该圈最后一列
int lastCol = n - i - 1;
// 如果该圈第一行就是最后一行,说明只剩下一行
if(i == lastRow){
for(int j = i; j <= lastCol; j++){
res.add(matrix[i][j]);
}
// 如果该圈第一列就是最后一列,说明只剩下一列
} else if(i == lastCol){
for(int j = i; j <= lastRow; j++){
res.add(matrix[j][i]);
}
} else {
// 第一行
for(int j = i; j < lastCol; j++){
res.add(matrix[i][j]);
}
// 最后一列
for(int j = i; j < lastRow; j++){
res.add(matrix[j][lastCol]);
}
// 最后一行
for(int j = lastCol; j > i; j--){
res.add(matrix[lastRow][j]);
}
// 第一列
for(int j = lastRow; j > i; j--){
res.add(matrix[j][i]);
}
}
}
return res;
}
}
2018/2
class Solution:
def spiralOrder(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: List[int]
"""
if (matrix is None or len(matrix) == 0):
return []
rows = len(matrix)
cols = len(matrix[0])
level = (min(rows, cols) + 1) // 2
result = []
for currLevel in range(0, level):
firstRow = currLevel
firstCol = currLevel
lastRow = rows - currLevel - 1
lastCol = cols - currLevel - 1
if firstRow == lastRow:
for col in range(firstCol, lastCol + 1):
result.append(matrix[firstRow][col])
return result
if firstCol == lastCol:
for row in range(firstRow, lastRow + 1):
result.append(matrix[row][firstRow])
return result
for col in range(firstCol, lastCol):
result.append(matrix[firstRow][col])
for row in range(firstRow, lastRow):
result.append(matrix[row][lastCol])
for col in range(lastCol, firstCol, -1):
result.append(matrix[lastRow][col])
for row in range(lastRow, firstRow, -1):
result.append(matrix[row][firstCol])
return result
Spiral Matrix II
Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order.
For example, Given n = 3,
You should return the following matrix:
[ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
顺序添加法
复杂度
时间 O(NM) 空间 O(1)
思路
本题就是按照螺旋的顺序把数字依次塞进去,我们可以维护上下左右边界的四个变量,一圈一圈往里面添加。最后要注意的是,如果n是奇数,要把中心那个点算上。
代码
public class Solution {
public int[][] generateMatrix(int n) {
int[][] res = new int[n][n];
int left = 0, right = n - 1, bottom = n - 1, top = 0, num = 1;
while(left < right && top < bottom){
// 添加该圈第一行
for(int i = left; i < right; i++){
res[top][i] = num++;
}
// 添加最后一列
for(int i = top; i < bottom; i++){
res[i][right] = num++;
}
// 添加最后一行
for(int i = right; i > left; i--){
res[bottom][i] = num++;
}
// 添加第一列
for(int i = bottom; i > top; i--){
res[i][left] = num++;
}
top++;
bottom--;
left++;
right--;
}
// 如果是奇数,加上中间那个点
if(n % 2 == 1){
res[n / 2][n / 2] = num;
}
return res;
}
}
2018/2
class Solution:
def generateMatrix(self, n):
"""
:type n: int
:rtype: List[List[int]]
"""
if n == 0:
return []
matrix = [[0 for i in range(0, n)] for j in range(0, n)]
left, right, top, bottom, num = 0, n - 1, 0, n - 1, 1
while left < right and top < bottom:
for col in range(left, right):
matrix[top][col] = num
num += 1
for row in range(top, bottom):
matrix[row][right] = num
num += 1
for col in range(right, left, -1):
matrix[bottom][col] = num
num += 1
for row in range(bottom, top, -1):
matrix[row][left] = num
num += 1
left += 1
right -= 1
top += 1
bottom -= 1
if n % 2 != 0:
matrix[left][top] = num
return matrix
后续 Follow Up
- 如果在matrix ii中,给出的是m和n来代表行数和列数,该如何解决?
i和ii的本质区别就是一个是任意长方形,一个是正方形,所以ii中不需要判断最后一行或者最后一列。既然没有了正方形的前提,那生成矩阵的方法就和i是一样的了。
class Solution:
def generateMatrix(self, m, n):
# m rows, n cols
if m == 0 or n == 0:
return []
matrix = [[0 for i in range(0, n)] for j in range(0, m)]
num = 1
level = (min(m, n) + 1) // 2
for currLevel in range(0, level):
lastRow = m - currLevel - 1
lastCol = n - currLevel - 1
firstRow = currLevel
firstCol = currLevel
if firstRow == lastRow:
for col in range(firstCol, lastCol + 1):
matrix[firstRow][col] = num
num += 1
return matrix
if firstCol == lastCol:
for row in range(firstRow, lastRow + 1):
matrix[row][firstRow] = num
num += 1
return matrix
for col in range(firstCol, lastCol):
matrix[firstRow][col] = num
num += 1
for row in range(firstRow, lastRow):
matrix[row][lastCol] = num
num += 1
for col in range(lastCol, firstCol, -1):
matrix[lastRow][col] = num
num += 1
for row in range(lastRow, firstRow, -1):
matrix[row][firstCol] = num
num += 1
return matrix
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。