剑指Offer-PHP实现

《剑指Offer》-29.顺时针打印矩阵

2018-08-17  本文已影响0人  懒人成长

题干

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

 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, 0),第二圈的起点就是(1, 1),依次类推,第n圈的起点就是 (n-1, n-1),又由于我们每循环一圈,都可能会输出两行两列的数据,所以我们现在来考虑下最后一圈起点坐标和行数、列数之间的关系,例如:如果是 8X8 的矩阵,则最后一圈的坐标是(3, 3),行数大于两倍的行坐标,即8>3*2,如果是 9X9 的矩阵,则最后一圈的坐标是 (4, 4),行数大于两倍的行坐标,即9>4*2,列数同理,由此我们可以分析得出,只要行数和列数都大于最后一圈的起点坐标的行和列,则还需要循环一圈。

对于第二个问题,我们需要考虑一些特殊情况了,对于行列相同的矩阵,每一圈循环都会按照从左到右,从上到下,从右到左,从下到上的四个步骤完成打印,而对于一些不规则的矩阵,如行数小于列数,行数大于列数时,需要特别分析一下,有可能出现缺少后面几步的情况。

到此,上面的两个问题就分析完了,可以代码实现了。

代码实现

<?php
/**
 * @param array $arr 二维数组
 * @param int $columns 列数
 * @param int $rows 行数
 */
function printMatrixClockwisely(array $arr, int $columns, int $rows)
{
    if ($arr == null || $columns == 0 || $rows == 0) {
        return;
    }
    $start = 0;
    while ($columns > $start * 2 && $rows > $start * 2) {
        printMatrixInCircle($arr, $columns, $rows, $start);
        $start++;
    }
}

/**
 * @param array $arr 二维数组
 * @param int $columns 列数
 * @param int $rows 行数
 * @param int $start 圈号
 */
function printMatrixInCircle(array $arr, int $columns, int $rows, int $start)
{
    // 从0开始,需要额外减1
    $endRow = $rows - $start - 1;
    $endColumn = $columns - $start - 1;

    // 从左至右输出
    for ($i = $start; $i <= $endColumn; $i++) {
        $num = $arr[$start][$i];
        printNum($num);
    }

    // 从上至下输出
    if ($endRow > $start) {
        for ($i = $start + 1; $i <= $endRow; $i++) {
            $num = $arr[$i][$endColumn];
            printNum($num);
        }
    }
    // 从右至左输出
    if ($endRow > $start && $endColumn > $start) {
        for ($i = $endColumn - 1; $i >= $start; $i--) {
            $num = $arr[$endRow][$i];
            printNum($num);
        }
    }

    // 从下至上输出
    if ($endColumn > $start && $endRow - $start > 1) {
        for ($i = $endRow - 1; $i > $start; $i--) {
            $num = $arr[$i][$start];
            printNum($num);
        }
    }
}

function printNum($num)
{
    printf('%3d', $num);
}


$arr = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]];
printMatrixClockwisely($arr, 4, 4);
上一篇 下一篇

猜你喜欢

热点阅读