本次题目
- 59 螺旋矩阵II
- 54 螺旋矩阵
- 剑指Offer 29 顺时针打印矩阵
59 螺旋矩阵II
- 螺旋循环为由外到内顺时针,注意循环的终止条件,循环次数为n/2向下取整(关于中心对称)。
- 每次螺旋循环分为从左到右,从上到下,从右到左,从下到上的四条边,每条边也要注意循环终止的条件,左闭右开,循环次数为螺旋循环的边界减一。
- 注意当n为奇数时,循环结束后要在中心补充最后一个元素。
class Solution {
public int[][] generateMatrix(int n) {
int[][] res = new int[n][n];
int loop = n/2;
int startX = 0;
int startY = 0;
int num = 1;
int count = n - 1;
while(loop > 0){
int i = startX;
int j = startY;
for(j = startY;j < count; j++){
res[i][j] = num++;
}
for(i = startY;i < count; i++){
res[i][j] = num++;
}
for(;j >startY; j--){
res[i][j] = num++;
}
for(;i >startX; i--){
res[i][j] = num++;
}
startX++;
startY++;
count -= 1;
loop--;
}
if(n % 2 == 1){
int cen = n/2;
res[cen][cen] = num;
}
return res;
}
}
54 螺旋矩阵
- 为上述题目的反向操作,注意两个循环的终止条件。由于矩阵不一定是方阵,因此螺旋循环的次数为min{m,n}/2向下取整。
- 每次循环中四条边的终止条件分为左右和上下。
- 当n为奇数时,中心位置可能是一行或一列或一个元素,起始位置与循环次数有关,每循环一次,中心的起始位置就向左(下)移动一个单位,终止位置就向右(上)移动一个单位。
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> res = new ArrayList<>();
int m = matrix.length;
int n = matrix[0].length;
int loop = Math.min(m/2, n/2) ;
int startX = 0;
int startY = 0;
int countLeftRight = n - 1;
int countUpDown = m - 1;
while(loop > 0){
int i = startX;
int j = startY;
for(j = startY; j < countLeftRight; j++){
res.add(matrix[i][j]);
}
for(i = startX; i < countUpDown; i++){
res.add(matrix[i][j]);
}
for(; j > startY; j--){
res.add(matrix[i][j]);
}
for(; i > startX; i--){
res.add(matrix[i][j]);
}
startX++;
startY++;
countLeftRight--;
countUpDown--;
loop--;
}
if(m > n){
if(n % 2 == 1){
int cen = n/2;
for(int i = cen; i < m - cen; i++){
res.add(matrix[i][cen]);
}
}
}else if(m < n){
if(m % 2 == 1){
int cen = m/2;
for(int j = cen; j < n - cen; j++){
res.add(matrix[cen][j]);
}
}
}else{
if(m % 2 == 1){
int cen = n/2;
res.add(matrix[cen][cen]);
}
}
return res;
}
}
剑指Offer 29 顺时针打印矩阵
- 同(1),但是输入矩阵可能为空(m=0),返回数据类型为int[ ]。
class Solution {
public int[] spiralOrder(int[][] matrix) {
if(matrix.length == 0){
int[] res = {};
return res;
}
int m = matrix.length;
int n = matrix[0].length;
int[] res = new int[m*n];
int num = 0;
int loop = Math.min(m/2, n/2) ;
int startX = 0;
int startY = 0;
int countLeftRight = n - 1;
int countUpDown = m - 1;
while(loop > 0){
int i = startX;
int j = startY;
for(j = startY; j < countLeftRight; j++){
res[num] = matrix[i][j];
num++;
}
for(i = startX; i < countUpDown; i++){
res[num] = matrix[i][j];
num++;
}
for(; j > startY; j--){
res[num] = matrix[i][j];
num++;
}
for(; i > startX; i--){
res[num] = matrix[i][j];
num++;
}
startX++;
startY++;
countLeftRight--;
countUpDown--;
loop--;
}
if(m > n){
if(n % 2 == 1){
int cen = n/2;
for(int i = cen; i < m - cen; i++){
res[num] = matrix[i][cen];
num++;
}
}
}else if(m < n){
if(m % 2 == 1){
int cen = m/2;
for(int j = cen; j < n - cen; j++){
res[num] = matrix[cen][j];
num++;
}
}
}else{
if(m % 2 == 1){
int cen = n/2;
res[num] = matrix[cen][cen];
num++;
}
}
return res;
}
}