首页 > 试题广场 > 顺时针打印矩阵
[编程题]顺时针打印矩阵
  • 热度指数:784756 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下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.
推荐
/*解题思路:顺时针打印就是按圈数循环打印,一圈包含两行或者两列,在打印的时候会出现某一圈中只包含一行,要判断从左向右打印和从右向左打印的时候是否会出现重复打印,同样只包含一列时,要判断从上向下打印和从下向上打印的时候是否会出现重复打印的情况*/
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 回复(52)
# -*- 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)
# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        if len(matrix) == 0:
            return None
        list1 = []
        left = 0
        down = len(matrix)-1
        up = 0
        right = len(matrix[0])-1
        while True:
            for i in range(left,right+1):
                list1.append(matrix[up][i])
            up +=1
            if up >down:
                break
            for i in range(up,down+1):
                list1.append(matrix[i][right])
            right -=1
            if left >right&nbs***bsp;right <0:
                break
            for i in reversed(range(left,right+1)):
                list1.append(matrix[down][i])
            down -=1
            if up>down&nbs***bsp;down <0:
                break
            for i in reversed(range(up,down+1)):
                list1.append(matrix[i][left])
            left +=1
            if left >right:
                break
        return list1

发表于 2020-01-09 13:01:47 回复(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
            # 将剩余二维列表逆时针旋转,继续pop,结果即为顺时针打印序列
            matrix = self.turn(matrix)
        return result
    
    # 逆时针旋转
    def turn(self, matrix):
        r = len(matrix)
        c = len(matrix[0])
        res = []
        for i in reversed(range(c)):
            res.append([matrix[j][i] for j in range(r)])
        return res

发表于 2019-12-31 19:53:07 回复(0)
class Solution:   
    def matrixp(self,list1,matrix,rows,colums,start):
        #endx是用来生成横坐标轴,endy是用来生成纵坐标轴
        endx=colums-1-start
        endy=rows-1-start
        #一圈循环分为四个部分,首先是打印第一行
        for i in range(start,endx+1):
           list1.append(matrix[start][i])
        #只有超过两行时,才进行打印最后一列
        if endy>start:
           for i in range(start+1,endy+1):
               list1.append(matrix[i][endx])
        #最起码两行两列
        if endx>start and endy>start:
            #此处为倒叙打印最后一行
           for i in range(endx-1,start-1,-1):
               list1.append(matrix[endy][i])
        #最起码三行两列
        if start<endx and start<endy-1:
            #此处为倒叙打印第一列
           for i in range(endy-1,start,-1):
               list1.append(matrix[i][start])
    def printMatrix(self, matrix):
        # write code here
        #计算行和宽
        rows=len(matrix)
        colums=len(matrix[0])
        #虽然说的是打印出,但是你还是需要返回一个list变量
        list1=[]
        #左上角第一个
        start=0
        #因为是从对角线处一圈圈开始,所以向中间走时,左上有一个,右下有一个,所以应该计算行或者列超过了其*2之后的值
        while(colums>start*2 and rows>start*2):
            #while进行循环,沿对角线逐渐向下
                self.matrixp(list1,matrix,rows,colums,start)
                start=start+1
        return list1
我遇到的奇葩问题是这个题目中不是说的打印嘛,最后怎么变成返回列表才行,真坑,差评

编辑于 2019-12-10 20:53:00 回复(0)
Python:

# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        res = [] 
        while matrix:
            res += matrix.pop(0)  #pop为取栈 默认是取出最后一个维度的数据 index=-1
            matrix = list(map(list, zip(*matrix)))[::-1]
        return res

发表于 2019-12-07 19:30:24 回复(0)
# -*- coding:utf-8 -*-
# 解题思路:深度优先搜索的变形,方向是自动调整的不是写死的
# 方向调整条件:数组越界和下一个节点已经遍历过
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        if not matrix:
            return []
        m = len(matrix)
        n = len(matrix[0])
        dp = [[0 for i in range(n)] for i in range(m)]
        pd = ((0, 1), (1, 0), (0, -1), (-1, 0))
        res = list()

        def visit(x, y, flag):
            change_count = 0
            res.append(matrix[x][y])
            dp[x][y] = 1

            (k, l) = pd[flag]
            if 0 <= x + k < m and 0 <= y + l < n and dp[x + k][y + l] == 0:
                visit(x + k, y + l, flag)
            else:
                while not (0 <= x + k < m and 0 <= y + l < n and dp[x + k][y + l] == 0):
                    flag = (flag + 1) % 4
                    (k, l) = pd[flag]
                    change_count += 1
                    # 判断如果换了4此方向,那么没路可走了,结束
                    if change_count == 4:
                        return

                visit(x + k, y + l, flag)

        visit(0, 0, 0)
        return res

发表于 2019-12-03 14:51:54 回复(0)
提供一个不错的思路,python编程
我的思路不是绕着矩阵来打印,而是让矩阵旋转,我每次打印他的第一行就行。
打印一次,去除第一行,然后旋转,最后就可以完成了。
# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        # 旋转矩阵
        def rotate(mat):
            lenx = len(mat[0])
            leny = len(mat)
            newmat = [[0] * leny for i in range(lenx)]
            for i in range(len(newmat)):
                newmat[i] = [mat[y][lenx - i - 1] for y in range(leny)]   
            return newmat

        # 获取第一行,并且旋转矩阵
        def getline(mat):
            res = mat[0]
            newmat = []
            if len(mat) > 1:
                newmat = rotate(mat[1:])
            return res,newmat
        
        result = []
        newm = []
        result, newm = getline(matrix)
        while newm != []:
            res,newm = getline(newm)
            result.extend(res)
        return result


发表于 2019-12-03 10:59:13 回复(0)
# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        if matrix is None:
            return
        row = len(matrix)  
        if row == 0:
            return
        if matrix[0] is None:
            return
        else:
            col = len(matrix[0])
        left_up_x, left_up_y = 0, 0
        right_up_x, right_up_y = 0, col - 1
        left_down_x, left_down_y = row - 1, 0
        right_down_x, right_down_y = row - 1, col - 1
        out_list = []
        while left_up_x <= right_down_x or left_up_y <= right_down_y:
            if left_up_x == right_down_x and left_up_y == right_down_y:
                out_list.append(matrix[left_up_x][right_down_y])
                break
            if left_up_x == right_down_x:
                for i in range(left_up_y, right_down_y + 1):
                    #print(i)
                    out_list.append(matrix[left_up_x][i])
                break
            if left_up_y == right_down_y:
                for i in range(left_up_x, right_down_x + 1):
                    #print(i)
                    out_list.append(matrix[i][right_down_y])
                break  
            if left_up_y <= right_down_y:
                for i in range(left_up_y, right_down_y):
                    #print(i)
                    out_list.append(matrix[left_up_x][i])
            if left_up_x <= right_down_x:
                for i in range(left_up_x, right_down_x):
                    #print(i)
                    out_list.append(matrix[i][right_down_y])
            if left_up_y < right_down_y:
                for i in range(right_down_y, left_up_y, -1):
                    #print(i)
                    out_list.append(matrix[right_down_x][i])
            if left_up_x < right_down_x:
                for i in range(right_down_x, left_up_x, -1):
                    #print(i)
                    out_list.append(matrix[i][left_up_y])
            left_up_x += 1
            left_up_y += 1
            right_up_x += 1
            right_up_y -= 1
            right_down_x -= 1
            right_down_y -= 1
            left_down_x -= 1
            left_down_y += 1
        out_list = [str(each) for each in out_list]
        print(",".join(out_list))
        return
发表于 2019-11-17 22:33:08 回复(0)
设四个边界,在边界里取值,以添加的总个数作为结束条件
# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        b=len(matrix)-1
        r=len(matrix[0])-1
        t=l=0
        s=len(matrix)*len(matrix[0])
        c=0
        res=[]
        while c<=s:
            for i in range(l,r+1):
                res.append(matrix[t][i])
                c+=1
            t+=1
            if c==s:
                return res
            for i in range(t,b+1):
                res.append(matrix[i][r])
                c+=1
            r-=1
            if c==s:
                return res
            for i in range(r,l-1,-1):
                res.append(matrix[b][i])
                c+=1
            b-=1
            if c==s:
                return res
            for i in range(b,t-1,-1):
                res.append(matrix[i][l])
                c+=1
            l+=1
            if c==s:
                return res


发表于 2019-10-24 13:46:15 回复(0)
# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        output = []
        while(1):
            output.extend(matrix[0])
            if len(matrix)==1 :
                break
            else:
                matrix = matrix[1:]
                m = reversed(list(map(list,zip(*matrix))))
                new_matrix = []
                for mi in m:
                    new_matrix.append(mi)
                matrix = new_matrix
        return output
Hint:
顺时针打印可以看成“输出矩阵的第一行”+“逆时针旋转剩余未打印部分矩阵”的组合动作(见一些回答中称之为魔方旋转)
矩阵逆时针旋转可以看成为“矩阵转置”+“矩阵翻转”的组合动作,采用
m = reversed(list(map(list,zip(*matrix))))
矩阵顺时针旋转可以看成为“矩阵翻转”+“矩阵转置”的组合动作,注意先后顺序不同导致的结果不同
输出output采用的是extend,而非append
编辑于 2019-10-17 15:17:03 回复(0)
# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        res=[]
        while matrix:
            res+=matrix.pop(0)
            if not matrix:
                break
            matrix=self.turn(matrix)
        return res
    def turn(self,matrix):
        rows=len(matrix)
        cols=len(matrix[0])
        newmat=[]
        for i in range(cols-1,-1,-1):
            newmat2=[]
            for j in range(rows):
                newmat2.append(matrix[j][i])
            newmat.append(newmat2)
        return newmat

发表于 2019-10-03 11:41:13 回复(0)
# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        visit = set([(0,0)])
        i = 0; j = 0
        result = [matrix[0][0]]
        row = len(matrix); column = len(matrix[0])
        
        while len(visit) != row * column:
            
            
            while (i, j+1) not in visit and j+1 < column :
                j += 1
                result.append(matrix[i][j])
                visit.add((i,j))
                
            while (i+1, j) not in visit and i+1 < row: 
                i += 1
                result.append(matrix[i][j])
                visit.add((i,j))
                
            while (i, j-1) not in visit and j-1 >= 0:
                j -= 1
                result.append(matrix[i][j])
                visit.add((i,j))
                
            while (i-1, j) not in visit and i-1 >= 0: 
                i -= 1
                result.append(matrix[i][j])
                visit.add((i,j))
                
            
        return result
        # write code here
研究了半天的python代码。。。想实现的方法不是这样的。。
发表于 2019-09-12 20:01:51 回复(0)