【剑指offer】顺时针打印矩阵

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

则依次打出数字 1、2、3、4、12、13、14、5、11、16、15、6、10、9、8、7。


自己的解法:

void print_cube(const int n)
{
    assert( n > 0 );
    int array[n][n]; // 用以保留数据
    
    int num = n; // 圈范围
    int s = 0;
    int line_index = 0, row_index = 0; // 数组下标

    // 将所有数据元素初始化为 0
    for( line_index = 0; line_index < n; line_index++ )
        for( row_index = 0; row_index < n; row_index++ )
            array[line_index][row_index] = 0;
   
    // 循环赋值
    line_index = 0, row_index = 0;
    while( line_index + 1 < num ) // line_index + 1 是因为数组下标从 0 开始,num 从 1 开始
    {
        for( ; row_index < num - 1 ; row_index++ )
            array[line_index][row_index] = ++s;
        for( ; line_index < num - 1; line_index++ )
            array[line_index][row_index] = ++s;
        for( ; row_index > n - num; row_index-- )
            array[line_index][row_index] = ++s;
        for( ; line_index > n - num; line_index-- )
            array[line_index][row_index] = ++s;

        line_index++, row_index++, num--; // 移动数组下标进次圈内
    }
    if( n % 2 == 1 ) array[line_index][row_index] = ++s; // 特殊处理奇数最后一个值, 即 (line_index + 1 == num) 时

    // 打印数组
    for( line_index = 0; line_index < n; line_index++ )
    {
        for( row_index = 0; row_index < n; row_index++ )
            cout << " " << array[line_index][row_index] << " ";
        cout << endl;
    }
}

剑指offer启发(矩阵并不是方阵):所以应当使用贪心法以面对特殊情况

特殊情况:

void print_matrix_clockwisely( const int columns, const int rows )
{
    if( columns <= 0 || rows <= 0 )  // 处理异常入参
    {
        cout << "Invalid parameters" << endl;
        return;
    }

    // 矩形元素值初始化
    int array[columns][rows], index_x, index_y;
    for( index_x = 0; index_x < columns; index_x++ )
        for( index_y = 0; index_y < rows; index_y++ )
            array[index_x][index_y] = 0;

    int number = 0;
    int start = 0; // 一圏的首位置下标,行列相同

    // 赋值都遵循贪心法
    while( columns > 2 * start && rows > 2 * start )
    {
        int end_x = columns - start;
        int end_y = rows - start;
        
        for( index_x = start, index_y = start; index_y < end_y && index_x < end_x; index_y++ ) // 从左到右赋值矩形上边的一行
            array[index_x][index_y] = ++number;

        if( start + 1 < end_x ) // 从上到下赋值矩形右边的一列
        {
            for( index_x = start + 1, index_y = end_y - 1; index_x < end_x; index_x++ )
                array[index_x][index_y] = ++number;
        }

        if( start + 1 < end_x && start + 1 < end_y ) // 从右到左赋值矩形下边的一行
        {
            for( index_x = end_x - 1, index_y = end_y - 2; index_y >= start; index_y--)
                array[index_x][index_y] = ++number;
        }

        if( start + 1 < end_x && start + 1 < end_y ) // 从下到上赋值矩形左边的一行
        {
            for( index_x = end_x - 2, index_y = start; index_x > start; index_x-- )
                array[index_x][index_y] = ++number;
        }

        start++;
    }

    // 打印矩形
    for( index_x = 0; index_x < columns; index_x++ )
    {
        for( index_y = 0; index_y < rows; index_y++ )
            cout << " " << array[index_x][index_y] << " ";
        cout << endl;
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值