首页 > 试题广场 >

顺时针打印矩阵

[编程题]顺时针打印矩阵
  • 热度指数:985141 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下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]
数据范围:
0 <= matrix.length <= 100
0 <= matrix[i].length <= 100

示例1

输入

[[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]
示例2

输入

[[1,2,3,1],[4,5,6,1],[4,5,6,1]]

输出

[1,2,3,1,1,1,6,5,4,4,5,6]
推荐
/*解题思路:顺时针打印就是按圈数循环打印,一圈包含两行或者两列,在打印的时候会出现某一圈中只包含一行,要判断从左向右打印和从右向左打印的时候是否会出现重复打印,同样只包含一列时,要判断从上向下打印和从下向上打印的时候是否会出现重复打印的情况*/
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;
    }
};


编辑于 2015-09-07 13:31:21 回复(55)
# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        res = []
        while matrix:
            res += matrix.pop(0)
            matrix = list(zip(*matrix))[::-1]
        return res

发表于 2022-03-28 23:23:05 回复(0)
超过100%python,记录旋转次数,两个if依次分别防止行数为1和列数为1的极端情况
# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        
        m=len(matrix)
        n=len(matrix[0])
        rotate=(min(m,n)+1)//2
        i=0
        res=[]
        x=0
        y=0
        while i<rotate:
            for y in range(i,n-i):
                res.append(matrix[i][y])
            for x in range(i+1,m-i-1):
                res.append(matrix[x][n-i-1])
            if x!=m-i-1:
                for y in range(n-i-1,i-1,-1):
                    res.append(matrix[m-i-1][y])
            if y!=n-i-1:
                for x in range(m-i-2,i,-1):
                    res.append(matrix[x][i])
            i+=1
        return res


发表于 2021-06-17 22:26:43 回复(0)
思路(借鉴二楼思路,判断条件稍改):
        每次添加第一行,然后将数组进行逆时针旋转
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        res = []
        while matrix:
            # 获取第一行,并添加至数组(不可以使用append,会变成二维数组)
            res += matrix.pop(0)
            if not matrix:
                break
            matrix = turn(matrix)
        return res
    def turn(self,matrix):
        row = len(matrix)    # 行
        col = len(matrix[0])    # 列
        # 最后返回的二维/一维(最后一次循环)数组
        temp = []
        
        # 逆时针旋转,将第一列放置新数组第一行,一次排放,最后对二维数组逆序,第一行变成最后一行
        for i in range(col):
            temp2 = []
            # 将某一列所有元素放入对应一行
            for j in range(row):
                temp2.append(matrix[j][i])
            temp.append(temp2)
        # 行 逆转
        temp.reverse()
        return temp


发表于 2021-04-12 20:47:51 回复(0)
# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here,可以模拟魔方逆时针旋转的方法,一直做取出第一行的操作
        result = []
        while matrix:
            result += matrix.pop(0)   # 取出第一行
            matrix = list(zip(*matrix)[::-1])
        return result

发表于 2021-03-17 08:55:28 回复(0)

python解法:只是判断是否重复存储的方法不同;
解法一:采用边界条件来控制存储;

"""
解法1:类似NC38螺旋数组;
# 1.从左到右:i=[left,right], matrix[top][i]
# 2.从上到下:i=[top+1,bottom], matrix[i][right]
# 3.从右到左:i=[right-1,left], matrix[bottom][i]
# 4.从下到上:i=[bottom-1,top+1], matrix[i][left]
# 注意:如何避免重复存储!采用边界条件来控制存储!
"""
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        res = []
        if len(matrix) == 0:
            return res
        left,top = 0,0
        bottom = len(matrix)-1
        right = len(matrix[0])-1
        while left <= right and top <= bottom:
            # 1.从左到右:i=[left,right], matrix[top][i]
            for i in range(left,right+1):
                res.append(matrix[top][i])

            # 2.从上到下:i=[top+1,bottom], matrix[i][right]
            for i in range(top+1,bottom+1):
                res.append(matrix[i][right])

            # 3.从右到左:i=[right-1,left], matrix[bottom][i]
            if top != bottom:
                for i in range(right-1,left-1,-1):
                    res.append(matrix[bottom][i])

            # 4.从下到上:i=[bottom-1,top+1], matrix[i][left]
            if left != right:
                for i in range(bottom-1,top,-1):
                    res.append(matrix[i][left])

            top += 1
            bottom -= 1
            left += 1
            right -= 1
        return res

解法二:计算一共存储了多少个元素来控制重复存储;

"""
解法2:
1.从左到右:i=[left,right], matrix[top][i]
2.从上到下:i=[top+1,bottom], matrix[i][right]
3.从右到左:i=[right-1,left], matrix[bottom][i]
4.从下到上:i=[bottom-1,top+1], matrix[i][right]
注意:如何避免重复存储!计算一共存储了多少个元素。
"""
class Solution:
    def printMatrix(self , matrix ):
        res = []
        if len(matrix) == 0:
            return res
        top, left = 0, 0
        bottom = len(matrix) - 1
        right = len(matrix[0]) - 1
        num = (bottom+1) * (right+1)
        while num > 0:
            # 判断全部元素是否存储完毕
            # 1.从左到右:i=[left,right], matrix[top][i]
            for i in range(left,right+1):
                if num > 0:
                    res.append(matrix[top][i])
                    num -= 1

            # 2.从上到下:i=[top+1,bottom], matrix[i][right]
            for i in range(top+1,bottom+1):
                if num > 0:
                    res.append(matrix[i][right])
                    num -= 1

            # 3.从右到左:i=[right-1,left], matrix[bottom][i]
            for i in range(right-1,left-1,-1):
                if num > 0:
                    res.append(matrix[bottom][i])
                    num -= 1

            # 4.从下到上:i=[bottom-1,top+1], matrix[i][left]
            for i in range(bottom-1,top,-1):
                if num > 0:
                    res.append(matrix[i][left])
                    num -= 1

            top += 1
            right -= 1
            bottom -= 1
            left += 1
        return res
发表于 2021-02-18 21:32:57 回复(0)
class Solution:
    # matrix类型为二维列表,需要返回列表
    def spin(self, mat):
        new_mat = []
        n = len(mat)
        m = len(mat[0])
        for i in range(m-1,-1,-1):
            row = []
            for j in range(n):
                row.append(mat[j][i])
            new_mat.append(row)
        return new_mat
    
    def printMatrix(self, matrix):
            # write code here
            tube = []
            while matrix:
                tube += matrix.pop(0)
                if matrix != []:
                        matrix = self.spin(matrix)
                else:
                        break
            return tube

发表于 2020-10-13 23:37:56 回复(0)
# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        if not matrix:
            return None
        if len(matrix) == 1:
            return([ele for ele in matrix[0]])
        elif len(matrix[0]) == 1:
            return([ele[0] for ele in matrix])
        else:
            i = 0 # 行起始
            j = 0 # 列起始
            m = len(matrix)   # 行终点
            n = len(matrix[0])   # 列终点
            allList = []
            while i < m and j < n:
                circleList = self.printCircle(i, j, m, n, matrix)
                allList += circleList
                i += 1
                j += 1
                m -= 1
                n -= 1
            return allList
            
    def printCircle(self, i, j, m, n, matrix):
        circleList = []
        for k in range(j, n):
            circleList += [matrix[i][k]]
        if m-1 > i:
            for k in range(i+1, m):
                circleList += [matrix[k][n-1]]
        if m-1 > i and n-1 > j:
            for k in range(n-2, j-1, -1):
                circleList += [matrix[m-1][k]]
        if m-1 > i+1 and n > j:
            for k in range(m-2, i, -1):
                circleList += [matrix[k][j]]
        return circleList

发表于 2020-10-12 18:07:38 回复(0)
暴力解法:先算外圈,在算里圈,进行迭代。
# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        if matrix == []:
            return None
        # 如果matrix为:n行1列
        elif len(matrix[0])==1:
            res=[]
            for i in range(len(matrix)):
                res.append(matrix[i][0])
            return res
        # 如果matrix为: 1行n列
        elif len(matrix)==1:
            res=[]
            for i in range(len(matrix[0])):
                res.append(matrix[0][i])
            return res
        else:# matrix: m行n列
            res=[]
            rows = len(matrix)
            columns = len(matrix[0])
            leftup=0
            leftdown=rows-1
            rightup =columns-1
            while leftup < leftdown and leftup < rightup:
                for i in range(leftup,rightup):
                    res.append(matrix[leftup][i])
                for j in range(leftup,leftdown):
                    res.append(matrix[j][rightup])
                for ii in range(rightup,leftup,-1):
                    res.append(matrix[leftdown][ii])
                for jj in range(leftdown,leftup,-1):
                    res.append(matrix[jj][leftup])
                leftup += 1
                leftdown -=1
                rightup -= 1
                if leftup == leftdown:
                    for i in range(leftup,rightup+1):
                        res.append(matrix[leftup][i])
            return res

发表于 2020-08-13 10:16:06 回复(0)
贡献一种思路简单的解法。位置不变,边走边删。
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        #双数   0,0-0,3  1,3-3,3  3,2-3,1
        result=[]
        try:
            while True:
                result+=matrix.pop(0)
                for i in range(len(matrix)):result.append(matrix[i].pop(-1))
                result+=matrix.pop(-1)[::-1]
                for i in range(len(matrix)):result.append(matrix[len(matrix)-i-1].pop(0))
        except:
            return result


发表于 2020-08-10 13:33:55 回复(0)
# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        result = []
        while matrix:
            result += matrix.pop(0)
            if not matrix :
                break
            else:
                matrix = self.turn(matrix)
        return result
    def turn(self,matrix):
        rows = len(matrix)
        cols = len(matrix[0])
        matrix2 = []
        for i in range(cols):
            list = []
            for j in range(rows):
                list.append(matrix[j][i])
            matrix2.append(list)
        matrix2.reverse()
        #注意不要直接用 return matrix2.reverse()
        return matrix2
        
可以模拟魔方逆时针旋转的方法,一直做取出第一行的操作
例如 
1 2 3
4 5 6
7 8 9
输出并删除第一行后,再进行一次逆时针旋转,就变成:
6 9
5 8
4 7
继续重复上述操作即可。
发表于 2020-08-04 21:29:26 回复(0)
# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        def t(M):
            shang=M.pop(0)
            return shang,M
        def r(M):
            
            you=[]
            for i in range(len(M)):
                you.append(M[i].pop())
            for i in range(len(M)-1,-1,-1):
                if len(M[i])==0:
                    M.pop(i)
            return you,M
        def b(M):
            xia=M.pop()
            xia.reverse()
            return xia,M
        def l(M):
            zuo=[]
            for i in range(len(M)):
                zuo.append(M[i].pop(0))
            for i in range(len(M)-1,-1,-1):
                if len(M[i])==0:
                    M.pop(i)
            zuo.reverse()
            return zuo,M
        
        
        re=[]
        while matrix:
            if len(matrix)==0:
                return re
            re1 ,matrix=t(matrix)
            re.extend(re1)
            if len(matrix)==0:
                return re
            re1 ,matrix=r(matrix)
            re.extend(re1)
            if len(matrix)==0:
                return re
            re1 ,matrix=b(matrix)
            re.extend(re1)
            if len(matrix)==0:
                return re
            re1 ,matrix=l(matrix)
            re.extend(re1)
            
            
        return re
            
                
            
            
            
            
                
            
        # write code here

发表于 2020-05-27 15:46:06 回复(0)
# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        res = []       
        while matrix:     
            res += matrix.pop(0)   #[1,2,3,4],相当于上
            if matrix and matrix[0]:          
                for row in matrix:       
                    #res存放每行的最后一个元素[1, 2, 3, 4, 8, 12, 16],相当于右
                    res.append(row.pop())   #pop(index)默认index=-1移除列表中的最后一个元素   
            #此时matrix去掉了第一行和每行的最后一个元素
            if matrix:      
                res += matrix.pop()[::-1]    #将matrix最后一行倒序输出,相当于下
            if matrix and matrix[0]:     
                for row in matrix[::-1]:  #倒序遍历矩阵的行   ,从最下一行开始
                    res.append(row.pop(0))     #输出每行的第一个元素,相当于左
        return res
发表于 2020-05-26 10:43:19 回复(0)
转置+reverse
class Solution:
    def printMatrix(self, matrix):
        # write code here
        a = len(matrix)
        result=[]
        while a != 1:
            for i in matrix[0]:
                result.append(i)
            matrix.pop(0)
            matrix = [[row[i] for row in matrix] for i in range(len(matrix[0]))]
            matrix.reverse()
            a = len(matrix)
        else:
            for i in matrix[0]:
                result.append(i)
        return result


发表于 2020-05-17 11:18:01 回复(0)
我的思路是:设置一个方向数组,二维数组中元素每次移动后若逾界或碰到之前经过的节点,则更换方向。这个更换方向的次序是固定的(顺时针),当所有方向换一遍后依然无用,说明已到达最后节点,跳出循环即可。
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        # 方向指针,每次移动时和4取余获得坐标增量
        directory = [(0,1),(1,0),(0,-1),(-1,0)]
        rows , cols=  len(matrix), len(matrix[0])
        path = [ [True]*cols for i in range(rows) ]
        seq = []
        # the start pos
        x,y = 0,0
        step, End = 0, False
        while True:
            seq.append(matrix[x][y])
            path[x][y] = False
            # let's move
            lsp = step
            nx, ny = x+ directory[step%4][0], y+ directory[step%4][1]
            while nx<0 or nx>=rows or ny<0 or ny>=cols or path[nx][ny]==False:
                step +=1
                if step - lsp ==4:
                    End = True
                    break
                nx, ny = x + directory[step % 4][0], y + directory[step % 4][1]
            # no way to move
            if End:
                break
            x, y = x+ directory[step%4][0], y+ directory[step%4][1]
        return seq


编辑于 2020-03-24 11:08:04 回复(0)

递归解法

# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        def print_mat(mat, x, y, height, width, res_list):
            if height <= 0 or width <= 0:
                return res_list
            if height == 1:
                for i in range(0, width):
                    res_list.append(mat[x][y + i])
                return res_list
            if width == 1:
                for i in range(0, height):
                    res_list.append(mat[x + i][y])
                return res_list
            res_list.append(mat[x][y])
            for i in range(1, width - 1):
                res_list.append(mat[x][y + i])
            res_list.append(mat[x][y + width - 1])
            for i in range(1, height - 1):
                res_list.append(mat[x + i][y + width - 1])
            res_list.append(mat[x + height - 1][y + width - 1])
            for i in range(width - 2, 0, -1):
                res_list.append(mat[x + height - 1][y + i])
            res_list.append(mat[x + height - 1][y])
            for i in range(height - 2, 0, -1):
                res_list.append(mat[x + i][y])
            return print_mat(mat, x + 1, y + 1, height - 2, width - 2, res_list)

        if not matrix:
            return None
        if not matrix[0]:
            return None
        res_list = []
        return print_mat(matrix, 0, 0, len(matrix), len(matrix[0]), res_list)
编辑于 2020-03-10 22:49:27 回复(0)

绕外圈打印
注意行列数不等的情况

# -*- coding:utf-8 -*-
"""
绕外圈打印
注意行列数不等的情况
"""
class Solution:
    def printMatrix(self, matrix):
        res = []
        if not len(matrix):
            return res
        else:
            rows = len(matrix)
            cols = len(matrix[0])
            n = min(rows,cols)
            x, y = 0, 0
            for i in range(0,int((n+1)/2)):
                rowRange = (i,rows-i)
                colRange = (i,cols-i)
                # left to right
                for y in range(colRange[0], colRange[1]):
                    res.append(matrix[x][y])
                # only one row left
                if(rowRange[1] - rowRange[0] ==1):
                    break
                # up to down
                for x in range(rowRange[0]+1, rowRange[1]):
                    res.append(matrix[x][y] )
                # only one col left
                if(colRange[1] - colRange[0] == 1):
                    break
                # right to left
                for y in range(colRange[1]-2, colRange[0]-1,-1):
                    res.append(matrix[x][y] )
                # down to up
                for x in range(rowRange[1]-2, rowRange[0],-1):
                    res.append(matrix[x][y] )
            return res


s = Solution()
matrix = [[1]]
ans = s.printMatrix(matrix)
print(ans)
编辑于 2020-02-27 17:04:35 回复(0)
class Solution:
    def printMatrix(self, matrix):
        res = []
        while matrix:
            res += matrix.pop(0)
            if matrix:
                matrix = self.rotate(matrix)
        return res
    def rotate(self,matrix):
        row = len(matrix)
        col = len(matrix[0])
        new_matrix = []
        for i in range(col):
            new_line = []
            for j in range(row):
                new_line.append(matrix[j][col-1-i])
            new_matrix.append(new_line)
        return new_matrix

发表于 2020-02-23 22:34:19 回复(0)
class Solution:
# matrix类型为二维列表,需要返回列表
def printMatrix(matrix):
(801)# write code here
if not len(matrix):
return None

r = len(matrix)-1
l = len(matrix[0])-1

ans = []
epochs = min(r,l)//2 +1
k = 0
while k < epochs:

for i in range(k,l-k):
ans.append(matrix[k][i])
for i in range(k,r-k):
ans.append(matrix[i][l-k])
for i in range(l-k,k,-1):
print(i)
ans.append(matrix[r-k][i])
for i in range(r-k,k,-1):
ans.append(matrix[i][k])
k+=1
if len(matrix)%2:
ans.append(matrix[r//2][l//2])

return ans
自己的测试集上跑可以 但是值通过了36% 不懂文提出在那里 求大佬解答
编辑于 2020-02-21 23:33:35 回复(0)
用哈希表记录已经添加过的坐标防止撞墙
每一圈都是向右,向下,向左,向上的循环
这是通过的代码(事先预处理哈希表初始化了最外面一层):
    def print(self,matrix):
        res,count=[],{}
        for i in range(-1,len(matrix[0])+1):
            count[-1,i]=1
        for i in range(-1,len(matrix)+1):
            count[i,len(matrix[0])]=1
        for i in range(len(matrix[0]),-2,-1):
            count[len(matrix),i]=1
        for i in range(len(matrix),-2,-1):
            count[i,-1]=1
        i,j=0,0
        while not (i, j) in count:
            while not (i, j) in count:
                res.append(matrix[i][j])
                count[i, j] = 1
                j += 1
            j -= 1
            i += 1
            while not (i, j) in count:
                res.append(matrix[i][j])
                count[i, j] = 1
                i += 1
            i -= 1
            j -= 1
            while not (i, j) in count:
                res.append(matrix[i][j])
                count[i, j] = 1
                j -= 1
            j += 1
            i -= 1
            while not (i, j) in count:
                res.append(matrix[i][j])
                count[i, j] = 1
                i -= 1
            i += 1
            j += 1
        return res
很奇怪的是这种写法在本地没问题但通不过,有大佬愿意看看是怎么回事吗?
这个的第一圈有排数列数的约束,所以哈希表没有预处理:
    def printMatrix(self, matrix):
        if not matrix:return
        row,col=len(matrix),len(matrix[0])
        res,count=[],{}
        i,j=0,0
        while not (i,j) in count:
            while j<col and not (i,j) in count:
                res.append(matrix[i][j])
                count[i,j]=matrix[i][j]
                j += 1
            j-=1
            i+=1
            while i<row and not (i,j) in count:
                res.append(matrix[i][j])
                count[i, j] = matrix[i][j]
                i += 1
            i-=1
            j-=1
            while j>=0 and  not (i,j) in count:
                res.append(matrix[i][j])
                count[i,j] = matrix[i][j]
                j-=1
            j+=1
            i-=1
            while i>=0 and not (i,j) in count:
                res.append(matrix[i][j])
                count[i, j] = matrix[i][j]
                i-=1
            i+=1
            j+=1
        return res



发表于 2020-01-12 09:31:49 回复(0)