题目描述
有一副由NxN矩阵表示的图像,这里每个像素用一个int表示,请编写一个算法,在不占用额外内存空间的情况下(即不使用缓存矩阵),将图像顺时针旋转90度。
给定一个NxN的矩阵,请返回旋转后的NxN矩阵,保证N小于等于500,图像元素小于等于256。
测试样例:
[[1,2,3],[4,5,6],[7,8,9]],3
返回:
[[7,4,1],[8,5,2],[9,6,3]]
我的思路
- 转化后的矩阵相当于每行元素顺时针旋转了90°,不妨把问题简化对于单独一个元素如何旋转90°——得到算法:对于该元素的索引[i][j],在经过旋转后其索引为[j][n - i - 1]。然而若直接对原矩阵操作,必然会“钱一发动全身”,不妨引入一个新矩阵做为“缓冲”。
#include"stdafx.h"
#include<iostream>
#include<vector>
#include<typeinfo>
using namespace std;
//初始化二维向量,我没查到有什么高效的方法
vector<vector<int>> make_matrix(int n)
{
vector<vector<int>> new_vec;
for (int i = 0; i < n; i++)
{
vector<int> temp_vec(n, 0);
new_vec.push_back(temp_vec);
}
return new_vec;
}
class Transform
{
public:
vector<vector<int>> transformImage(vector<vector<int>> &vec)
{
int n = vec.size();
vector<vector<int>> new_vec = make_matrix(n);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
swap(vec[i][j], new_vec[j][n - i - 1]);
}
}
//待解决:两个vector的内存
return new_vec;
}
template<typename T>//想做成模板的,之后懒得弄了了
void traverse(vector<vector<T>> &vec)//遍历数列
{
for (vector<vector<T>>::iterator i = vec.begin(); i < vec.end(); i++)
{
for (vector<T>::iterator j = (*i).begin(); j<(*i).end(); j++)
{
cout << *j;
}
cout << endl;
}
}
};
void main()
{
vector<vector<int>> vec = { {1,2,3},{4,5,6},{7,8,9} };
Transform test;
vec = test.transformImage(vec);
test.traverse(vec);
}
分析算法
对于N*N矩阵,有n个输入
make_matrix函数中,访问向量n次,实际开销可能更大
transformImage,访问次数2n次。将返回值new_vec赋给vec,又有n次访问。
虽然整个算法时间复杂度O(n),但我觉得还有简化空间。
改进
transformImage可以直接改变vec,而不需要通过返回值来赋值给vec——我们的new_vec直接复制于vec,new_vec经过处理的数据扔到vec即可,改进后如下
class Transform
{
public:
void transformImage(vector<vector<int>> &vec,int angle)
{
int n = vec.size();
vector<vector<int>> new_vec = vec;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
switch (angle)//方便拓展API
{
case 90:
swap(new_vec[i][j], vec[j][n - i - 1]);
break;
case 180:
break;
}
}
}
}
template<typename T>//想做成模板的,之后懒得弄了了
void traverse(vector<vector<T>> &vec)//遍历数列
{
for (vector<vector<T>>::iterator i = vec.begin(); i < vec.end(); i++)
{
for (vector<T>::iterator j = (*i).begin(); j<(*i).end(); j++)
{
cout << *j;
}
cout << endl;
}
}
};
void main()
{
vector<vector<int>> vec = { {1,2,3},{4,5,6},{7,8,9} };
Transform test;
test.transformImage(vec,90);
test.traverse(vec);
}
我的算法在空间上创造了一个n的矩阵,我在想能不能在空间复杂度上做些文章