剑指offer_面试题20_顺时针打印矩阵(思路在一步步分解之中)

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

例如:如果输入如下矩阵:

 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。

思路如下:

算法如下:

#include <iostream>
#include <map>

using namespace std;

/*打印函数,这个函数传递二维数组用的形参 int arr[][columns],因此当传进来的二维函数维数变化时,就需要改动这里的columns值*/
/*可以把它改成 int ** arr,不过在传递的时候需要注意,传递指针的指针*/
void print_Matrix_InCircle(int arr[][5], int rows, int columns)   /**rows:行,columns:列*/
{
    if(NULL == arr || columns <= 0 || rows <= 0)
        return;

    int i = 0,j = 0;

    unsigned int k = 0;
    unsigned int all_number = rows * columns;
    int s[all_number];

    int n_c = columns, m_r = rows;   /**列,行*/

    map<int,int> word_count;
    for(int x = 0; x < columns; x++)
    {
        for(int y = 0; y < rows; y++)
        {
            word_count[arr[x][y]] = 0;
        }
    }

    while(n_c > 0 && m_r > 0)
    {
        /** 从左至右,剩余列数必须大于0 */
        if(n_c > 0 && i < rows && j < columns)     /**不要忘记 i、j 范围的判断*/
        {
            while(j < columns && !word_count[arr[i][j]])
            {
                s[k++] = arr[i][j];
                //cout << arr[i][j] << ' ';
                ++word_count[arr[i][j]];          /*标记已访问*/
                j++;
            }
            m_r--;  /*可供访问的行数减1*/
            j--;    /*退出之前 j 多加了一步*/
            i++;    /*i向下走一步*/
        }


        /** 从上至下,剩余行数必须大于0 */
        if(m_r > 0 && i < rows && j < columns)
        {
            while(i < rows && !word_count[arr[i][j]])
            {
                s[k++] = arr[i][j];
                //cout << arr[i][j] << ' ';
                //cout << arr[1][4] << ' ';
                ++word_count[arr[i][j]];
                i++;
            }
            n_c--;
            i--;
            j--;
        }

        /** 从右至左,剩余列数必须大于0 */
        if(n_c > 0 && i < rows && j < columns)
        {
            while(j >= 0 && !word_count[arr[i][j]])
            {
                s[k++] = arr[i][j];
                //cout << arr[i][j] << ' ';
                ++word_count[arr[i][j]];
                j--;
            }
            m_r--;
            j++;
            i--;
        }

        /** 从下至上,剩余行数必须大于0 */
        if(m_r > 0 && i < rows && j < columns)
        {
            while(i >= 0 && !word_count[arr[i][j]])
            {
                s[k++] = arr[i][j];
                //cout << arr[i][j] << ' ';
                ++word_count[arr[i][j]];
                i--;
            }
            n_c--;
            i++;
            j++;
        }
    }


    for(k = 0; k < all_number; k++)
    {
        cout << s[k] << ' ';
    }
    cout << endl;

}

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

    //int ** p = (int **)&arr1;
    //cout << p[1][1];
    //int (*p1)[4] = arr1;
    print_Matrix_InCircle(arr1,4,4);
    cout << endl;
*/
/**
    int arr2[5][5] ={
        {1,2,3,4,5},
        {6,7,8,9,10},
        {11,12,13,14,15},
        {16,17,18,19,20},
        {21,22,23,24,25}
    };
    int (*p2)[5] = arr2;
    print_Matrix_InCircle(p2,5,5);
    cout << endl;
*/

    int arr3[4][5] ={
        {1,2,3,4,5},
        {6,7,8,9,10},
        {11,12,13,14,15},
        {16,17,18,19,20},
    };
    //int (*p3)[5] = arr3;
    print_Matrix_InCircle(arr3,4,5);

/**
    int arr4[1][5] ={
        {1,2,3,4,5}
    };
    print_Matrix_InCircle(arr4,1,5);
    cout << endl;
*/
/**
    int arr5[5][1] ={
        {1},
        {2},
        {3},
        {4},
        {5}
    };
    print_Matrix_InCircle(arr5,5,1);
    cout << endl;
*/
/**
    int arr6[1][1] ={
        {1}
    };
    print_Matrix_InCircle(arr6,1,1);
    cout << endl;
*/
/**
    int arr7[2][2] ={
        {1,2},
        {3,4}
    };

    print_Matrix_InCircle(arr7,2,2);
    cout << endl;
*/
    return 0;
}
结果如下:


以下是 设置 指针的指针 来指向二维数组的方法:

void Test(int columns, int rows)
{
    printf("Test Begin: %d columns, %d rows.\n", columns, rows);

    if(columns < 1 || rows < 1)
        return;

    int** numbers = new int*[rows];        /*注意这里,要给它分配空间*/
                                           /*给一个指向 含有rows个int元素数组的 指针分配了存储空间,并将这个指针,赋给了 number指针*/
    for(int i = 0; i < rows; ++i)
    {
        numbers[i] = new int[columns];     /*注意这里,number[i] 也是一个指针,指向一个数组元素,也需要给它分配空间*/
        for(int j = 0; j < columns; ++j)
        {
            numbers[i][j] = i * columns + j + 1;
        }
    }

    print_Matrix_InCircle(numbers, columns, rows);    /*传递 指针的指针*/
    printf("\n");

    for(int i = 0; i < rows; ++i)
        delete[] (int*)numbers[i];

    delete[] numbers;
}

需要注意二维数组指针的问题,如:

int arr[5][6];

int (*p)[6] = arr;     /* p 是一个指向有 6 个数组元素数组的指针,注意这是一个指向一维数组的指针 */

如果 (int **)强制转换,也不行,转换后无法操作二维数组数据。


/**点滴积累,我的一小步O(∩_∩)O~*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值