顺时针打印矩阵----《剑指offer》面试题20

题目

  输入一个矩阵,按照从外向里以顺时针的顺序依次打印出第一个数字。如图:如果输入以下矩阵:

在这里插入图片描述

思路

  由于是以从外圈到内圈的顺序依次打印,我们可以把矩阵想象成若干个圈,每一次打印矩阵中的一个圈。
在这里插入图片描述
如果以最外圈开始打印,那么每一圈开始打印的位置是从左上角开始的。如果矩阵的行数是rows,列数是columns。则左上角的坐标是(0,0),(1,1),(2,2) … ,我们以(start,start)做为每一圈开始打印的位置。start从0开始。

  让循环继续的条件是: cloumns > start * 2 && rows > start * 2

  如何顺时针打印一圈
  打印一圈分为四步:第一步从左到右打印一行;第二步从上到下打印一列;第三步从右到左打印一行;第四步从下到上打印一列。

  但是,最后一圈有特殊情况:
如果最后一圈只有一行:因为第一步总是要走的,所以只走第一步。
如果最后一圈只有一列:走完第二步。
如果最后一圈至少有两行两列:走完第三步。
如果最后一圈至少有三行两列:走完第四步。

代码

#include <iostream>


//  打印矩阵的一圈
void PrintMatrixInCircle(int** numbers, int rows, int columns, int start)
{
    // endX:横向边界, endY:纵向边界
    int endX = columns - 1 - start;
    int endY = rows - 1 - start;

    // 从左往右打印一行
    for (int i = start; i <= endX; ++i)
        std::cout << numbers[start][i] << ' ';

    // 如果当前矩阵有两行或以上,则从上到下打印一列
    if (start < endY)
    {
        for (int i = start + 1; i <= endY; ++i)
            std::cout << numbers[i][endX] << ' ';
    }

    // 如果当前矩阵有两行或以上,且不少于两列,则从右往左打印一行
    if (start < endY && start < endX)
    {
        for (int i = endX - 1; i >= start; --i)
            std::cout << numbers[endY][i] << ' ';
    }

    // 如果当前矩阵有三行或者以上,且不少于两列,则从下往上打印一列
    if (start < endY - 1 && start < endX)
    {
        for (int i = endY - 1; i >= start + 1; --i)
            std::cout << numbers[i][start] << ' ';
    }

}

//  顺时针打印矩阵
void PrintMatrixClockWisely(int** numbers, int rows, int columns)
{
    if (numbers == nullptr || columns <= 0 || rows <= 0)
        return;

    // start: 开始打印位置; 每一圈从(start,start)位置开始打印,0表示最外圈
    int start = 0;

    //  判断最内圈的条件: start == std::min(columns,rows) / 2
    while (columns > start * 2  && rows > start * 2)
    {
        PrintMatrixInCircle(numbers, rows, columns, start);
        ++start;
    }
}


int main()
{

//    int matrix[1][5] = { 1,2,3,4,5 }; //  只有一行
//    int matrix[5][1] = { {1},{2},{3},{4},{5} };   //  只有一列
//    int matrix[3][4] = { {1,2,3,4}, {10,11,12,5}, {9,8,7,6} };    //  列多于行
    int matrix[4][3] = { {1,2,3}, {10,11,4}, {9,12,5}, {8,7,6} };   //  行多于列

    int rows = 4;
    int columns = 3;

    int *ptr_arr[rows];    //指针数组
    for(int i = 0; i < rows; ++i)
    {
        ptr_arr[i] = matrix[i];
    }

    PrintMatrixClockWisely(ptr_arr, rows, columns);

    return EXIT_SUCCESS;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值