190
推荐
/*解题思路:顺时针打印就是按
查看全部
编辑于 2015-09-07 13:31:21
回复(53)
127
python solution: 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
发表于 2017-10-13 21:42:14
回复(34)
459
//很惭愧,编译了多次才通过的代码。。
/*
思想,用左上和右下的坐标定位出一次要旋转打印的数据,一次旋转打印结束后,往对角分别前进和后退一个单位。
提交代码时,主要的问题出在没有控制好后两个for循环,需要加入条件判断,防止出现单行或者单列的情况。
*/
class Solution {
public:
vector printMatrix(vector > matrix) {
int row = matrix.size();
int col = matrix[0].size();
vector 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;
}
};
编辑于 2015-08-29 23:32:18
回复(69)
349
可以模拟魔方逆时针旋转的方法,一直做取出第一行的操作
例如
1 2 3
4 5 6
7 8 9
输出并删除第一行后,再进行一次逆时针旋转,就变成:
6 9
5 8
4 7
继续重复上述操作即可。
Python代码如下
class Solution:
# matrix类型为二维列表,需要返回列表
def printMatrix(self, matrix):
# write code here
result = []
while(matrix):
result+=matrix.pop(0)
if not matrix or not matrix[0]:
break
matrix = self.turn(matrix)
return result
def turn(self,matrix):
num_r = len(matrix)
num_c = len(matrix[0])
newmat = []
for i in range(num_c):
newmat2 = []
for j in range(num_r):
newmat2.append(matrix[j][i])
newmat.append(newmat2)
newmat.reverse()
return newmat
编辑于 2016-08-16 20:09:28
回复(86)
116
//主体循环部分才5行。其实是有规律可循的。将每一层的四个边角搞清楚就可以打印出来了
import java.util.ArrayList;
public class Solution {
public ArrayList printMatrix(int [][] array) {
ArrayList result = new ArrayList ();
if(array.length==0) return result;
int n = array.length,m = array[0].length;
if(m==0) return result;
int layers = (Math.min(n,m)-1)/2+1;//这个是层数
for(int i=0;i
for(int k = i;k
for(int j=i+1;j
for(int k=m-i-2;(k>=i)&&(n-i-1!=i);k--) result.add(array[n-i-1][k]);//右至左
for(int j=n-i-2;(j>i)&&(m-i-1!=i);j--) result.add(array[j][i]);//左下至左上
}
return result;
}
}
编辑于 2015-06-22 00:41:47
回复(33)
76
import java.util.ArrayList;
public class Solution {
ArrayList a=new ArrayList(); new一个数组 以便下面函数能调用
public ArrayList printMatrix(int [][] matrix) {
int tR=0;
int tC=0;
int dR=matrix.length-1;
int dC=matrix[0].length-1;
while(tR<=dR&&tC<=dC){ 左上边界最多到达右下边界 用于判断是否还是剥圈打印
printEdge(matrix,tR++,tC++,dR--,dC--);
}
return a;
}
public void printEdge(int [][] m,int tR,int tC,int dR,int dC){
if(tR==dR){ 先判断是否只是一横行 如果是 打印该横行的列(通常用于内圈)
for(int i=tC;i<=dC;i++){
a.add(m[tR][i]);
}
}
else if(tC==dC){ 再判断是否只是一竖列 如果是 打印该横行的列(通常用于内圈
for(int i=tR;i<=dR;i++){
a.add(m[i][tC]);
}
}
else {
int curC=tC;用2个变量储存 用于判断当前位置
int curR=tR;
while(curC!=dC){ 当前位置未到达当前行的最右列 --》往右去
a.add(m[tR][curC]);
curC++;
}
while(curR!=dR){ 当前位置未到达当前列的最底行 --》往下去
a.add(m[curR][dC]);
curR++;
}
while(curC!=tC){ 当前位置未到达当前行的最左列 --》往左去
a.add(m[dR][curC]);
curC--;
}
while(curR!=tR){ 当前位置未到达当前列的最顶行 --》往上去
a.add(m[curR][tC]);
curR--;
}
}
}
}
这个思路个人觉得看起来比上面的都要清晰 虽然较长 但是其实分析起来很简单 ,就是一个剥圈的函数,这个函数 核心就是 左上点和右下点 每次走完剥圈函数之后 左上角坐标++,右下角-- 往圈内移 如果觉得好 可以点点顶上去 让别人也看到
发表于 2018-02-07 22:00:44
回复(13)
27
顺着走,即向右->向下->向左->向上,一共要走(长*宽)步。遇到边界就改变方向,当向上碰到顶的时候,四个边界都缩小。思路简单,一个循环即可!
class Solution {
public:
vector printMatrix(vector > matrix) {
vector ret;
if(matrix.empty())return ret;
int x,y,cnt=matrix[0].size()*matrix.size();
int rEdge=matrix[0].size()-1,dEdge=matrix.size()-1,lEdge=0,uEdge=0;
//bool first=true;
for(x=0,y=0;cnt>0;cnt--){
ret.push_back(matrix[x][y]);
//;2
//go right
if(x==uEdge){if(y
else if(y==rEdge){x++;}
continue;}
//down
if(y==rEdge){if(x
else if(x==dEdge){y--;}
continue;}
//left
if(x==dEdge){if(y>lEdge)y--;
else if(y==lEdge){x--;}
continue;}
//up
if(y==lEdge){if(x>uEdge+1)x--;
else if( x==uEdge+1){y++;lEdge++;uEdge++;rEdge--;dEdge--;}
continue;}
//;3
}
return ret;
}
编辑于 2017-08-20 05:05:38
回复(7)
33
//借鉴的二楼的代码,对二楼的代码进行了部分判断条件的修改
class Solution {
public:
vector printMatrix(vector > matrix) {
int row = matrix.size();
int col = matrix[0].size();
vector result;
// 输入的二维数组非法,返回空的数组
if (row == 0 || col == 0) return result;
int top = 0, left = 0, right = col-1, bottom = row-1;
while(top <= bottom && left<= right){
//left to right
for(int i = left; i <= right; ++i) result.push_back(matrix[top][i]);
//top tp bottom
for(int i = top+1; i <= bottom; ++i) result.push_back(matrix[i][right]);
//right to left
for(int i = right-1; i >= left && top < bottom; --i) result.push_back(matrix[bottom][i]);
//bottom to top
for(int i = bottom-1; i > top && right > left; --i) result.push_back(matrix[i][left]);
++top; ++left; --right; --bottom;
}
return result;
}
};
发表于 2017-06-21 11:25:04
回复(14)
39
没做出来,我思路跟他们截然不同,他们什么意思我也没看明白
期望智商可以再上线一些
-----------------------------------------------------------------------------------------
updata20171008
这道题其实蛮难的
以第一种解法来说,不是眼见着一个for循环里面再包进去四个for循环那么简单的;
解决这道题里包含的一系列逻辑层次我现在整理、呈现出来如下:
第一轮要理清的问题是:确定这个需求的具体实现过程是怎么样的
那也就是按照矩阵数据,一层层的画圈出来
那么这一画整个需求实现过程也就清晰了:究竟哪一部分是变量,哪一部分是循环量
第二轮要理清的问题也就出来了:从过程中确定出整个过程中的变量与循环量,这两个量即构成了第一层循环
第三轮要理清的问题就是确定第一层循环的循环主体,依然是回到需求的的实现过程中,在每一圈中都做了什么,也就是确定那四个循环
第四轮,从数据携带的信息中挖掘出每一层循环主体所需要的判断条件,这个最终是一组或几组数学表达式
对以上再进一步抽象,能得到类似问题的一般解决步骤,这里我再思考思考进行总结,暂时不写在这里了。
回到具体每一步的算法,首先就是要得到圈数:((row
很绝望的说,这个问题其实是难的,我前前后后想很久。。。具体思考是: 为什么获取行列中最小的那个?尝试着在矩阵上画一个方形圈出来,只能以行/列中最小的为参考才能画出一个圈,否则以最大的为参考这个圈是画不出来的,因为最短边不够长
圈数到底怎么算的?所谓的圈其实是一个方形,那么很显然只要有两行或者两列就得到一个圈,所以圈数=行or列/2。加一和减一是为了进行取舍。这里回头我会上图。
得到了圈数后下一个难点就是从数据中挖掘出数学表达式成为每一层循环体的限定条件了
第一个层循环的限定条件就是圈数
第二层循环的限定条件是在圈数的基础上得来的各条限定公式。此处需要上图说明
暂时先更新到这个地步吧,回头还有第二种解法需要总结。泪目,就这么一道小题,其实超级耗费时间,因为密度很大,很多东西可以从中提炼到,所以其实是非常值得的。
编辑于 2017-10-08 13:54:41
回复(6)
23
/*
* 采用旋转魔方的方式 一次取一行,然后旋转
*/
public ArrayList printMatrix_2(int[][] matrix) {
ArrayList al = new ArrayList<>();
int row = matrix.length;
while (row != 0) {
for (int i = 0; i < matrix[0].length; i++) {
al.add(matrix[0][i]);
}
if (row == 1)
break;
matrix = turn(matrix);
row = matrix.length;
}
return al;
}
private int[][] turn(int[][] matrix) {
// TODO 自动生成的方法存根
int col = matrix[0].length;
int row = matrix.length;
int[][] newMatrix = new int[col][row - 1];
for (int j = col - 1; j >= 0; j--) {
for (int i = 1; i < row; i++) {
newMatrix[col - 1 - j][i - 1] = matrix[i][j];
}
}
return newMatrix;
}
public ArrayList printMatrix_1(int[][] matrix) {
ArrayList al = new ArrayList<>();
int row = matrix.length;
if (row == 0)
return al;
int col = matrix[0].length;
// 短的边/2,向上取整
int circle = ((row > col ? col : row) + 1) / 2;
for (int i = 0; i < circle; i++) {
// 从左向右打印,j=i; j
// 这一行的前i个已经在第i圈从下往上被打印,故j=i
// 倒数i个都已经在第i圈从上往下被打印,故j=col-i-1
for (int j = i; j < col - i; j++)
al.add(matrix[i][j]);
// 从上往下打印,j=i+1;j
// 这一列的前i+1个已经在从左向右打印时被打印,故j=i+1
// 倒数i个已经在第i圈从右往左被打印,故j=row-i-1
for (int j = i + 1; j < row - i; j++)
al.add(matrix[j][col - i - 1]);
// 从右往左打印,j=col-i-2;j>=i&&row-i-1!=i;,
// 这一行倒数i个已经在第i圈从上往下被打印
// 这一行倒数第i+1个已经在从上往下时被打印,故j=col-1-(i+1)=col-i-2
// 这一行的前i个已经在从下往上时被打印,故j=i>=i
// 当第i圈为0时即从未由上往下打印时,col有多列时,会造成重复打印,故判断row-i-1!=i以避免
for (int j = col - i - 2; j >= i && row - i - 1 != i; j--)
al.add(matrix[row - i - 1][j]);
// 从下往上打印,j=row-i-2;j>i&&col-i-1!=i,
// 这一列倒数i个已经在第i圈从右往作被打印
// 这一列倒数第i+1个已经在从右往左时被打印,故j=row-1-(i+1)=row-i-2
// 这一列的前i个已经在第i圈从左往右时被打印,
// 这一列的第i+1个已经在本圈从左往右被打印,故j=i+1>i
// 当第i圈为0时即从未由右向左打印时,row有多行时,会造成重复打印,故判断col-i-1!=i以避免
for (int j = row - i - 2; j > i && col - i - 1 != i; j--)
al.add(matrix[j][i]);
}
return al;
}
编辑于 2017-06-08 21:13:48
回复(2)
22
1.每次都是一个圈,所以定义四个变量限定每次循环的界限:
startRow,endRow,startCol,endCol;
2.分别把首行,末列,末行,首列的数据依次加入list;
3.注意不要重复加入某个点,每次都要限定界限。
代码如下:
public ArrayList printMatrix(int [][] matrix) {
int row = matrix.length;
if(row==0)
return null;
int col = matrix[0].length;
if(col==0)
return null;
ArrayList list = new ArrayList();
int startRow = 0;
int endRow = row-1;
int startCol = 0;
int endCol = col-1;
while(startRow<=endRow&&startCol<=endCol){
//如果就剩下一行
if(startRow==endRow){
for(int i=startCol;i<=endCol;i++)
list.add(matrix[startRow][i]);
return list;
}
//如果就剩下一列
if(startCol==endCol){
for(int i=startRow;i<=endRow;i++)
list.add(matrix[i][startCol]);
return list;
}
//首行
for(int i=startCol;i<=endCol;i++)
list.add(matrix[startRow][i]);
//末列
for(int i=startRow+1;i<=endRow;i++)
list.add(matrix[i][endCol]);
//末行
for(int i=endCol-1;i>=startCol;i--)
list.add(matrix[endRow][i]);
//首列
for(int i=endRow-1;i>=startRow+1;i--)
list.add(matrix[i][startCol]);
startRow = startRow + 1;
endRow = endRow - 1;
startCol = startCol + 1;
endCol = endCol - 1;
}
return list;
}
编辑于 2017-12-04 21:42:49
回复(4)
31
人生苦短,我用python;
用旋转魔法的方式,一直取出第一行;
例如
1 2 3
4 5 6
7 8 9
输出并删除第一行后,变为
4 5 6
7 8 9
再进行一次逆时针旋转,就变成:
6 9
5 8
4 7
继续重复上述操作即可。
编辑于 2016-09-04 16:02:53
回复(12)
10
题目描述
题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 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.
解题思路
旋转打印有点难,不过也是有办法的。我们可以把矩阵想象为一个魔方,我读完第一行之后,我就把魔方左转90度,再读取第一行,这样循环,直到最后一行结束。具体看代码中注释。
我的答案 /**************************
用旋转魔方的方式,一直取出第一行;
例如
1 2 3
4 5 6
7 8 9
输出并删除第一行后,变为
4 5 6
7 8 9
再进行一次逆时针旋转,就变成:
6 9
5 8
4 7
继续重复上述操作即可。
***************************/
import java.util.ArrayList;
public class Solution {
public ArrayList printMatrix(int [][] matrix) {
//作为存放结果的容器
ArrayList list = new ArrayList<>();
//拿到出事数组的行数
int row = matrix.length;
while(row != 0){
//将数组的第一行先添加进容器中
for(int i=0;i
list.add(matrix[0][i]);
//当行数等于1时就没有必要再继续执行了,在上面打印完之后就可以停止了
if(row == 1)
break;
//删除上面遍历的数组的第一行,然后旋转这个数组并返回
matrix = revert(matrix);
//更新行数
row = matrix.length;
}
//返回
return list;
}
private int[][] revert(int[][] matrix){
//拿到matrix的行数和列数
int rows = matrix.length;
int cols = matrix[0].length;
//因为我们要将原数组遍历过的第一行删除,然后旋转变成一个新的数组,所以先初始化一下这个新数组
int[][] newMatrix = new int[cols][rows-1];
//对这个新数组进行赋值
for(int j=cols-1;j>=0;j--){
for(int i=1;i
newMatrix[cols-j-1][i-1] = matrix[i][j];
}
}
//返回新数组
return newMatrix;
}
}
编辑于 2019-03-07 19:55:58
回复(1)
23
/*
* 1.选坐标为(0,0),(1,1)...的点记为(start,start)为开始坐标,下一圈开始坐标为(start+1,start+1)
* 2.判断是否进入下一圈(即是否打印完成)的条件是row>start*2 && column>start*2
* 3.打印一圈的左上角坐标为(start,start),右下角的坐标为(column-start-1,row-start-1)
* 4.根据一圈左上角和右下角坐标判断“从左到右”,“从上到下”,“从右到左”,“从下到上”哪些用打印,哪些不用
*/
class Solution {
public:
vector printMatrix(vector > matrix) {
if (matrix.empty()) {
return matrix[0];
}
int row = static_cast(matrix.size()) ;
int column = static_cast(matrix[0].size()) ;
int start = 0;
vector result;
result.clear();
while (column > start*2 && row > start*2) {
int endX = column - 1 - start;
int endY = row - 1 - start;
//从左到右打印一行
for (int i=start; i<=endX; i++) {
result.push_back(matrix[start][i]);
}
//从上到下打印一行
if (start
for (int i=start+1; i<=endY; i++) {
result.push_back(matrix[i][endX]);
}
}
//从右到左打印一行
if (start < endX && start < endY) {
for (int i=endX-1; i>=start; i--) {
result.push_back(matrix[endY][i]);
}
}
//从下到上打印一行
if (start
for (int i=endY-1; i>=start+1; i--) {
result.push_back(matrix[i][start]);
}
}
start++;
}
return result;
}
};
编辑于 2015-10-23 16:14:54
回复(8)
13
#打印第一行,删除第一行,逆时针转动90度。重复以上步骤,直到矩阵为空。
class Solution:
def printMatrix(self, matrix):
# write code here
s=[]
while matrix:
s+=matrix[0]
del matrix[0]
matrix=zip(*matrix)[::-1]
return s
发表于 2017-07-10 17:55:07
回复(8)
20
/**
* @description 顺时针打印矩阵
* @author GongchuangSu
* @since 2016.09.03
* @explain 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵:
* 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.
*/
import java.util.*;
public class Solution{
ArrayList list = new ArrayList<>();
public ArrayList printMatrix(int [][] matrix) {
int rows = matrix.length;
int columns = matrix[0].length;
int start = 0;
while(rows > start*2 && columns > start*2){
printMatrixInCircle(matrix, rows, columns, start);
start++;
}
return list;
}
/**
* 功能:打印一圈
*/
public void printMatrixInCircle(int [][] matrix, int rows, int columns, int start){
// 从左到右打印一行
for(int i = start; i < columns - start; i++)
list.add(matrix[start][i]);
// 从上到下打印一列
for(int j = start + 1; j < rows - start; j++)
list.add(matrix[j][columns - start - 1]);
// 从右到左打印一行
for(int m = columns - start - 2; m >= start && rows - start - 1 > start; m--)
list.add(matrix[rows - start - 1][m]);
// 从下到上打印一列
for(int n = rows - start - 2; n >= start + 1 && columns - start - 1 > start; n--)
list.add(matrix[n][start]);
}
}
发表于 2016-09-03 15:11:54
回复(12)
21
前进,转弯,...
class Solution {
int n, m;
vector > v;
bool judge(int i, int j){
return 0 <= i && i < n && 0 <= j && j < m && !v[i][j];
}
public:
vector printMatrix(vector > a) {
vector r;
if(!(n = a.size()) || !(m = a[0].size())) return r;
v = vector >(n, vector(m, false));
const int D[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
int i = 0, j = 0, d = 0, T = m * n;
while(T--){
r.push_back(a[i][j]);
v[i][j] = true;
if(!judge(i + D[d][0], j + D[d][1])) (++d) %= 4; //转弯
i += D[d][0], j += D[d][1];//前进
}
return r;
}
};
编辑于 2017-05-17 19:23:43
回复(6)
7
思路:
分为两个步骤:
1. 打印一圈
从左到右打印一行(这是一定有的)
当有两行及以上时,存在从上到下打印
当有两行及以上并有两列及以上时,存在从右到左
当有两列并有三行及以上时,存在从下到上打打印
2. 起点进入下一圈,即进入下一个循环
初始几点为(0, 0), 打印一圈后有(1, 1), 再打印一圈为(2, 2)
都存在行数 > 起点 * 2 并且列数 > 起点 * 2
简单来说就是, 如果把二维数组等分为四个部分 中点都为中心,那么起点肯定都位于左上部分。根据这个条件可以判断是否还有圈数
# -*- coding:utf-8 -*-
class Solution:
# matrix类型为二维列表,需要返回列表
def printMatrix(self, matrix):
# write code here
if not matrix:
return []
columns = len(matrix[0])
rows = len(matrix)
def printMatrixCircle(start):
endRow = rows - 1 - start
endColumn = columns - 1 - start
# 从左到右打印一行
for y in range(start, endColumn + 1):
result.append(matrix[start][y])
# 从上到下打印一列
if endRow > start:
for x in range(start + 1, endRow + 1):
result.append(matrix[x][endColumn])
# 从右到左打印一行
if endColumn > start and endRow > start:
for y in range(endColumn - 1, start - 1, -1):
result.append(matrix[endRow][y])
# 从下到上打印
if endRow > start + 1 and endColumn > start:
for x in range(endRow - 1, start, -1):
result.append(matrix[x][start])
start = 0
result = []
while columns > start * 2 and rows > start * 2:
printMatrixCircle(start)
start += 1
return result
编辑于 2016-07-25 09:45:26
回复(0)
5
# -*- coding:utf-8 -*-
class Solution:
def printMatrix(self, matrix):
result = []
while matrix:
result += matrix.pop(0)
if matrix:
matrix = [[row[col] for row in matrix] for col in reversed(range(len(matrix[0])))] # 逆时针旋转
return result
发表于 2018-08-10 17:31:46
回复(2)
5
class Solution {
public:
vector printMatrix(vector > matrix) {
vector v;
if(matrix.size()==0||matrix[0].size()==0)return v;
int a=0,x=matrix.size()-1,y=matrix[0].size()-1,i,j;
do{
for(i=a,j=a;j<=y;j++) v.push_back(matrix[i][j]);
for(i=a+1,j=y;i<=x;i++) v.push_back(matrix[i][j]);
if(a!=x)for(i=x,j=y-1;j>=a;j--) v.push_back(matrix[i][j]);
if(a!=y)for(i=x-1,j=a;i>=a+1;i--) v.push_back(matrix[i][j]);
}while(++a<=--x&&a<=--y);
return v;
}
};
发表于 2015-08-07 17:05:39
回复(3)
7
import java.util.ArrayList;
public class Solution {
public ArrayList printMatrix(int [][] matrix) {
ArrayList ls = new ArrayList();
int colStart = 0;
int colEnd = matrix[0].length;
int lineStart = 0;
int lineEnd = matrix.length;
int count = lineEnd * colEnd;
if (matrix == null)
return ls;
while (count != 0) {
for(int i = colStart;i
ls.add(matrix[lineStart][i]);
count--;
}
lineStart++;
if(count==0)
break;
for(int i = lineStart;i
ls.add(matrix[i][colEnd-1]);
count--;
}
colEnd--;
if(count==0)
break;
for(int i = colEnd-1;i>=colStart;i--){
ls.add(matrix[lineEnd-1][i]);
count--;
}
lineEnd--;
if(count==0)
break;
for(int i = lineEnd-1;i>=lineStart;i--){
ls.add(matrix[i][colStart]);
count--;
}
colStart++;
if(count==0)
break;
}
return ls;
}
}
发表于 2016-06-30 17:20:49
回复(1)