您的位置:首页 > 职场人生

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

2015-08-13 21:31 786 查看
题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

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

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~*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: