面试题20:顺时针打印矩阵(Leetcode-54和57)

来源:互联网 发布:linux对文件内容排序 编辑:程序博客网 时间:2024/05/21 01:57

一.打印矩阵

题目:输入一个矩阵,从外向里顺时针打印出每一个数字,例如输入以下矩阵:
这里写图片描述
输出:1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10。

分析:可以把这个问题分解为各个小圈,每圈按照顺时针来访问。
这里写图片描述

对于5*5的矩阵而言,最后一圈只有一个数字,其坐标是(2,2),我们发现5>2*2;
对于6*6的矩阵而言,最后一圈有4个数字,其左上角坐标还是(2,2),我们发现6>2*2依然成立;
于是,我们得出循环结束的条件是:

columns>startX*2和rows>startY*2

所以我们有如下循环来打印矩阵:

void PrintMatrix(int matrix[][3], int rows, int columns){    if(matrix == NULL || rows <= 0 || columns <= 0)    {        return;    }    int start = 0;    while(rows > start*2 && columns > start*2)    {        PrintMatrixHelper(matrix, rows, columns, start);        start++;    }}

注意:二维数组的传参要指定第二维数组的大小,不能直接用int来传参。**
PrintMatrixHelper函数如何实现呢?
按照顺时针方向来,有四个方向:
1. 从左往右
2. 从上往下
3. 从右往左
4. 从下往上
我们可以按照这个思路,依次遍历。
注意的第3步和第4步,需要判断这一行和这一列是否已经遍历过,即判断endX和start大小,endY和start大小

void PrintMatrixHelper(int matrix[][3], int rows, int columns, int start){    int endX = columns - 1 - start;    //从左往右打印    for(int i=start; i <= endX; ++i)    {        printf("%d,", matrix[start][i]);    }    int endY = rows - 1 - start;    //从上往下打印    for(int i=start+1; i <= endY; ++i)    {        printf("%d,", matrix[i][endX]);    }    //从右往左打印,要判断所在行是否大于start,否则会重复打印    if(start < endY)    {        for(int i=endX-1; i >= start; --i)        {            printf("%d,", matrix[endY][i]);        }    }    //从下往上打印,要判断所在列是否大于start,否则会重复打印    if(start < endX)    {        for(int i=endY-1; i > start; --i)        {            printf("%d,", matrix[i][start]);        }    }}

测试用例:

矩阵有多行多列,一行多列,多行一列,一行一列。
主函数如下:

//int matrix[4][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13,14,15,16}};//int matrix[3][3] = {{1,2,3}, {4,5,6}, {7,8,9}};//int matrix[1][3] = {{1,2,3}};//int matrix[3][1] = {{1},{2},{3}};//int matrix[3][2] = {{1,2},{3,4},{5,6}};int matrix[1][1] = {{1}};PrintMatrix(matrix, 1, 1);

Leetcode-54(Spiral Matrix)中传入参数是vector<vector<int>>,返回值为vector<int>,思路是一样的。

二. 螺旋生成N平方矩阵

思路与上面差不多,只是在helper函数里,多一个引用传递参数start_value,用于记录遍历到哪一个数了。
另外vector<vector<int>>的动态初始化也要注意。

vector<vector<int>> generateMatrix(int n) {    vector<vector<int> > ret(n, vector<int>(n, 1));    if(n <= 0)    {        return ret;    }    int start = 0;    int start_value = 1;    while(n > start*2)    {        generateMatrixHelper(n, start, start_value, ret);        start++;    }    return ret;    }void generateMatrixHelper(int n, int start, int &start_value, vector<vector<int>>& matrix){    int end = n - 1 - start;    //从左往右填充数据    for(int i=start; i <= end; ++i)    {        matrix[start][i] = start_value;        start_value++;    }    //从上往下填充数据    for(int i=start+1; i <= end; ++i)    {        matrix[i][end] = start_value;        start_value++;    }    //从右往左填充数据,要判断所在行是否大于start,否则会重复填充    if(start < end)    {        for(int i=end-1; i >= start; --i)        {            matrix[end][i] = start_value;            start_value++;        }    }    //从下往上填充数据,要判断所在列是否大于start,否则会重复填充    if(start < end)    {        for(int i=end-1; i > start; --i)        {            matrix[i][start] = start_value;            start_value++;        }    }}
原创粉丝点击