2.顺时针打印矩阵
顺时针打印矩阵
[编程题]顺时针打印矩阵
时间限制:1秒空间限制:32768K
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
总结下来整体思路分为两大类:
1.按部就班,不改变矩阵形状,取行,取列,再逆向取行,逆向取列,(旋转打印)重复直到矩阵为空
2.一直只取第一行,取完逆时针转动整个矩阵90度,重复直到矩阵为空
一.C++解法
1.解题思路:顺时针打印就是按圈数循环打印,一圈包含两行或者两列,在打印的时候会出现某一圈中只包含一行,要判断从左向右打印和从右向左打印的时候是否会出现重复打印,同样只包含一列时,要判断从上向下打印和从下向上打印的时候是否会出现重复打印的情况
class Solution {
public:
vector<int> printMatrix(vector<vector<int> > matrix) {
vector<int>res;
res.clear();
int row=matrix.size();//行数
int collor=matrix[0].size();//列数
//计算打印的圈数
int circle=((row<collor?row:collor)-1)/2+1;//圈数
for(int i=0;i<circle;i++){
//从左向右打印
for(int j=i;j<collor-i;j++)
res.push_back(matrix[i][j]);
//从上往下的每一列数据
for(int k=i+1;k<row-i;k++)
res.push_back(matrix[k][collor-1-i]);
//判断是否会重复打印(从右向左的每行数据)
for(int m=collor-i-2;(m>=i)&&(row-i-1!=i);m--)
res.push_back(matrix[row-i-1][m]);
//判断是否会重复打印(从下往上的每一列数据)
for(int n=row-i-2;(n>i)&&(collor-i-1!=i);n--)
res.push_back(matrix[n][i]);}
return res;
}
};
2.用左上和右下的坐标定位出一次要旋转打印的数据,一次旋转打印结束后,往对角分别前进和后退一个单位。
class Solution {
public:
vector<int> printMatrix(vector<vector<int> > matrix) {
int row = matrix.size();
int col = matrix[0].size();
vector<int> res;
// 输入的二维数组非法,返回空的数组
if (row == 0 || col == 0) return res;
// 定义四个关键变量,表示左上和右下的打印范围
int left = 0, top = 0, right = col - 1, bottom = row - 1;
while (left <= right && top <= bottom)
{
// left to right
for (int i = left; i <= right; ++i) res.push_back(matrix[top][i]);
// top to bottom
for (int i = top + 1; i <= bottom; ++i) res.push_back(matrix[i][right]);
// right to left
if (top != bottom)
for (int i = right - 1; i >= left; --i) res.push_back(matrix[bottom][i]);
// bottom to top
if (left != right)
for (int i = bottom - 1; i > top; --i) res.push_back(matrix[i][left]);
left++,top++,right--,bottom--;
}
return res;
}
};
二.python解法
1.思路:
1、将第一行加入result中,同时删除第一行
2、使用魔方旋转的思路,将剩余矩阵整体逆时针旋转,继续取第一行
3、直到所有矩阵被删空为止
其实就是模拟魔方逆时针旋转的方法,一直做取出第一行的操作
例如
1 2 3
4 5 6
7 8 9
输出并删除第一行后,再进行一次逆时针旋转,就变成:
6 9
5 8
4 7
继续重复上述操作即可。
代码:
# -*- coding:utf-8 -*-
class Solution:
# matrix类型为二维列表,需要返回列表
def printMatrix(self, matrix):
if len(matrix) == 0:
return []
res = []
number = len(matrix) * len(matrix[0])
res.extend(matrix[0])
while len(res) < number:
matrix.pop(0)
matrix = self.turn(matrix)
res.extend(matrix[0])
return res
def turn(self, mat):
if len(mat) == 0:
return
turned_lst = [([0] * len(mat)) for i in range(len(mat[0]))]
for i in range(len(mat)):
for j in range(len(mat[0])):
turned_lst[j][i] = mat[i][len(mat[0]) - 1 - j]
return turned_lst
2.同理,模拟魔方的面,旋转矩阵,借助numpy包的nparray的arange,reshape等操作完成转的操作
# -*- coding:utf-8 -*-
import numpy as np
class Solution:
# matrix类型为二维列表,需要返回列表
def printMatrix(self, matrix):
# write code here
all = []
x, y = matrix.shape
print x, y
print matrix
for k in range(x + y):
all.append(matrix[0])
b = matrix[1:, ]
m, n = b.shape
print m, n
c = np.arange(m * n).reshape((n, m))
for i in range(m):
for j in range(n):
c[j][i] = b[i][n - 1 - j]
matrix = c
print matrix
print len(matrix)
if len(matrix) == 1:
all.append(matrix[0])
break
return all
3.直接旋转打印求解,创建一个res的list用来保存输出结果,循环执行旋转打印
1.将第一行直接赋值给res的list,同时在原矩阵中删除该行
2.利用行号逐个取最右侧列元素后append给res的list,append的同时删除值
3.利用切片你想取最底层行元素后append给res的list,append的同时删除值
2.然后利用行号+切片循环逆向截取最左侧列,完成旋转打印
class Solution:
def printMatrix(self, matrix):
res = []
while matrix:
res += matrix.pop(0) #行
if matrix and matrix[0]:
for row in matrix:
res.append(row.pop()) #列
if matrix:
res += matrix.pop()[::-1] #行
if matrix and matrix[0]:
for row in matrix[::-1]:
res.append(row.pop(0)) #列
return res
同理
class Solution:
def printMatrix(self, matrix):
ans=[]
row=len(matrix)
cols=len(matrix[0])
if cols==1 and row==1:
ans=[matrix[0][0]]
return ans
else:
for o in range((min(cols,row)+1)//2):
[ans.append(matrix[o][i]) for i in range(o,cols-o)]
[ans.append(matrix[j][cols-o-1]) for j in range(o,row-o) if matrix[j][cols-o-1] not in ans]
[ans.append(matrix[row-o-1][k]) for k in range(cols-1-o,o-1,-1) if matrix[row-o-1][k] not in ans]
[ans.append(matrix[l][o]) for l in range(row-1-o,o-1,-1) if matrix[l][o] not in ans]
return ans