剑19—顺时针打印矩阵

题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 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、二维数组的行列数,row,col
2、特殊测试用例判断
3、每圈对应的左上角坐标(start,start),从而分析循环继续的条件
col>startX*2 && row>startY*2,,,,,,,,,,,,,,,,,,,,,,startX=startY=start
打印第一圈的左上角坐标是(0,0),第二圈的左上角坐标(1,1),依此类推得到每圈的左上角坐标行标和列表总是相同的,于是取左上角(start,start)的一圈作为分析目标;
对于一个5*5矩阵,最后一圈只有1个数字,对应的左上角坐标为(2,2),发现5>2*2;
对于一个6*6矩阵,最后一圈只有4个数字,对应的左上角坐标为(2,2),发现6>2*2;
对于一个7*8矩阵,最后一圈只有1个数字,对应的左上角坐标为(3,3),发现8>3*2, 7>3*2;
4、如何实现打印一圈呢?对应的start++, 其中,用容器存储遍历的元素res.push_back
找出每圈对应的右下角坐标(endX,endY);
顺时针打印:注意边界
//从左到右打印一行
//从上到下打印一列+ 判断条件(纵坐标start小于endY)
//从右到左打印一行+ 判断条件(横坐标start小于endX,纵坐标start小于endY)
//从下到上打印一列+ 判断条件(横坐标start小于endX,纵坐标start小于endY-1)
5、利用vector的二维数组初始化,resize()

    vector<vector <int> > matrix(3);//3行一维数组
    for (int i = 0; i < 3; i++)
        matrix[i].resize(5);//每一维有5个元素,即3行5列数组
//法一:有子函数
#include<iostream>
#include<vector>
#include<iomanip>  //左对齐包含的头文件
using namespace std;

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;
        res.clear();
        int start = 0;

        while (col > start * 2 && row > start * 2)
        {
            res=PrintMatrixInCircle(matrix, col, row, start, res);
            ++start;
        }
        return res;
    }
    //把矩阵想象成若干个圈,顺时针循环打印矩阵中的每个圈
    vector<int> PrintMatrixInCircle(vector<vector<int> > matrix, int col, int row, int start, vector<int>res)
    {
        int endX = col - 1 - start;//列
        int endY = row - 1 - start;//行
        //从左到右打印一行
        for (int i = start; i <= endX; i++)
            res.push_back(matrix[start][i]);

        //从上到下打印一列+ 判断条件
        if (start < endY)  //纵坐标start小于endY
        {
            for (int i = start + 1; i <= endY; i++)
                res.push_back(matrix[i][endX]);
        }
        //从右到左打印一行+ 判断条件
        if (start < endX && start < endY)//横坐标start小于endX,纵坐标start小于endY
        {
            for (int i = endX - 1; i >= start; i--)
                res.push_back(matrix[endY][i]);
        }
        //从下到上打印一列+ 判断条件
        if (start < endX&&start < endY - 1)//横坐标start小于endX,纵坐标start小于endY-1
        {
            for (int i = endY - 1; i >= start + 1; i--)
                res.push_back(matrix[i][start]);
        }
        return res;
    }
};

//主函数
void main()
{
    Solution *s = new Solution;
    //vector<vector <int> > matrix(4, vector<int>(4,1));//m*n的二维vector,注意两个 "> "之间要有空格!

    vector<vector <int> > matrix(3);//3行一维数组
    for (int i = 0; i < 3; i++)
        matrix[i].resize(5);//每一维有5个元素,即3行5列

    for (int i = 0; i < 3; i++) 
    {
        for (int j = 0; j < 5; j++)
            matrix[i][j] = (i + 1)*(j + 1);
    }
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 5; j++)
            cout <<left<< setw(3) <<matrix[i][j]<<" ";//左对齐输出矩阵
        cout << endl;
    }
    vector<int>result;
    result = s->printMatrix(matrix);
    cout << "顺时针打印的矩阵为:" << endl;
    for (auto i : result)
        cout << i << " ";
    cout << endl;
}
//方法二:写在一个函数里
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 start = 0;//左上角坐标(start,start),(0,0),(1,1),(2,2)...

        while (col > start * 2 && row > start * 2)
        {
            //每圈对应的右下角坐标
            int endX = col - 1 - start;//列
            int endY = row - 1 - start;//行

            //从左到右打印一行
            for (int i = start; i <= endX; i++)
                res.push_back(matrix[start][i]);

            //从上到下打印一列+ 判断条件
            if (start < endY)
            {
                for (int i = start + 1; i <= endY; i++)
                    res.push_back(matrix[i][endX]);
            }
            //从右到左打印一行+ 判断条件
            if (start < endX && start < endY)
            {
                for (int i = endX - 1; i >= start; i--)
                    res.push_back(matrix[endY][i]);
            }
            //从下到上打印一列+ 判断条件
            if (start < endX && start < endY - 1)
            {
                for (int i = endY - 1; i >= start + 1; i--)
                    res.push_back(matrix[i][start]);
            }
            ++start;
        }
        return res;

    }
};

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值