周日晚上参加的腾讯实习生笔试,两个编程题不难,当时做了但是没看到结果,再重做一遍,记录一下。
问题:
输入一个整数n,输入n对应的蛇形矩阵,如 n =3 时,蛇形矩阵:
(最近刷Leetcode发现这是Leetcode原题 59. Spiral Matrix II)
187296345
程序功能
输入:3
输出:1 2 3 8 9 4 7 6 5(矩阵按行输出)
// C++ program to print snake mat
// for n =3 ;
// snake mat = [ 1 2 3
// 8 9 4
// 7 6 5]
#include<iostream>
#include<vector>
using namespace std;
class Solution {
public:
vector<vector<int>> SnakeMat(int n)
{
// enxt place is -1 if can go
vector<vector<int>> mat(n, vector<int>(n, -1));
//0: go right 1: go down, 2: go left 3: go up
int state = 0;
int i = 0, j = 0;
for (int cnt = 0; cnt < n*n; cnt++)
{
if (state == 0){
mat[i][j] = cnt + 1;
if (j < n - 1 && mat[i][j+1] == -1){j++; continue;}
else { state = 1; i++; }//then go down
}
else if (state == 1){
mat[i][j] = cnt + 1;
if (i < n - 1 && mat[i+1][j] == -1){ i++; continue; }
else { state = 2; j--; }//then go left
}
else if (state == 2){
mat[i][j] = cnt + 1;
if (j > 0 && mat[i][j-1] == -1){ j--; continue; }
else { state = 3; i--; }//then go up
}
else if (state == 3){
mat[i][j] = cnt + 1;
if (i > 0 && mat[i-1][j] == -1){ i--; continue; }
else { state = 0; j++; }//then go right
}
}
return mat;
}
void PrintMat(const vector<vector<int>>& mat)
{
for (int i = 0; i < mat.size(); i++){
for (int j = 0; j < mat[0].size(); j++){
std::cout << mat[i][j]<<" ";
}
std::cout << endl;
}
std::cout << endl;
}
};
// Driver program to test above function
int main()
{
Solution solution;
solution.PrintMat(solution.SnakeMat(10));
return 1;
}
// solution from Leetcode
// https://discuss.leetcode.com/topic/7282/simple-c-solution-with-explaination
class Solution {
public:
vector<vector<int> > generateMatrix(int n) {
vector<vector<int> > ret( n, vector<int>(n) );
int k = 1, i = 0;
while( k <= n * n )
{
int j = i;
// four steps
while( j < n - i ) // 1. horizonal, left to right
ret[i][j++] = k++;
j = i + 1;
while( j < n - i ) // 2. vertical, top to bottom
ret[j++][n-i-1] = k++;
j = n - i - 2;
while( j > i ) // 3. horizonal, right to left
ret[n-i-1][j--] = k++;
j = n - i - 1;
while( j > i ) // 4. vertical, bottom to top
ret[j--][i] = k++;
i++; // next loop
}
return ret;
}
};
一个更简洁的solution
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> mat(n, vector<int>(n, 0));
int i=0, j=0, di=0, dj=1;
for(int k=0; k<n*n; ){
mat[i][j]=++k;
if( mat[(i+di)%n][(n+j+dj)%n] ){
int temp = di;
di = dj;
dj = -temp;
}
i += di;
j += dj;
}
return mat;
}
};
算法的思路很简单,开始所有的位置都置为-1,这样遇到下一个位置值为-1代表没有走过,可以走的。算法从(0,0)位置开始,先向右走,一直走到 j=n-1的位置再向下走,走到 i= n-1,往左走;往左走到 j=0,就往上走,走到(1,0)时发现(0,0)不为-1了,再往左走,周而复始,一直走n*n步,停止循环。
另外,也可以直接按计算出来的步数走,因为每一次要走多少步是可以计算出来的,程序的复杂度是差不多的。
n =10 时程序运行结果: