顺时针顺序打印
记录圈数, 然后一圈一圈的打印。注意最后一圈只有一行或者一列的情况
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <unordered_map>
#include <list>
using namespace std;
vector<int> f(vector<vector<int>> v)
{
vector<int> res;
if (v.size() != 0)
{
int level = (int)(min(v[0].size() - 1, v.size() - 1)) / 2 + 1;
int length = static_cast<int>(v.size()), width = (int)v[0].size();
for (int i = 0; i < level; i++)
{
for (int j = i; j < width - i; j++)
{
res.push_back(v[i][j]);
}
for (int j = i + 1; j < length - i; j++)
{
res.push_back(v[j][width - i - 1]);
}
for (int j = width - i - 2; length - 2 * i != 1 && j >= i; j--) // 仅剩一行不用管
{
res.push_back(v[length - i - 1][j]);
}
for (int j = length - i - 2; width - 2 * i != 1 && j > i; j--) //仅剩一列不用管
{
res.push_back(v[j][i]);
}
}
}
return res;
}
int main()
{
vector<vector<int>> v;
int N = 5, M = 5;
for (int i = 0; i < N; i++)
{
vector<int> temp;
for (int j = 0; j < M; j++)
{
temp.push_back(i * M + j);
}
v.push_back(temp);
}
for (int i = 0; i < N; i++)
{
vector<int> temp;
for (int j = 0; j < M; j++)
{
printf("%2d ", v[i][j]);
}
putchar(10);
}
auto res = f(v);
cout << res.size() << endl;
for (auto i : res)
{
cout << i << " ";
}
putchar(10);
return 0;
}
z形打印, 利用副对角线i + j 属于[0, width + length - 2]的规律,按行遍历,控制列的范围即可。同时注意从上往下还是从下往上。
vector<int> f2(vector<vector<int>> v)
{
vector<int> res;
if (v.size() != 0)
{
int length = (int)v.size();
int width = (int)v[0].size();
int cnt = length + width - 2;
for (int i = 0; i <= cnt; i++)
{
if (i & 1)
{
for (int j = length - 1; j >= 0; j--)
{
if (i - j >= 0 && i - j < width)
{
res.push_back(v[j][i - j]);
}
}
}
else
{
for (int j = 0; j < length; j++)
{
if (i - j >= 0 && i - j < width)
{
res.push_back(v[j][i - j]);
}
}
}
}
}
return res;
}
旋转90度,规律太简单,不写了。