【ACM】顺时针打印矩阵
2015-06-17 12:41
344 查看
问题描述:
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,
例如,如果输入如下矩阵: 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.
算法描述:
以(x,y)元组作为当前打印元素的指针,当前位置加上-1,0,1分别
表示x,y坐标后退、保持不变和前进。如矩阵
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
若当前位置为(0,0),则打印1;
顺时针打印时,移动到下一个位置即x+1,y+0,故为(1,0),即打印2;
再往下,(2,0),打印3;
……
最后一个元素则是(1,2),打印10.
首先检测是否为单行单列,若是,则只需一个for循环即可解决,否则进入下一步:
从坐标(0,0)开始,x依次递增,y不变,同时,记录x,y的最大最小值x_min,x_max和y_min.y_max,然后开始移动坐标;
当移到边界位置(x_max,y_min)时,表明第一行已打印完,故x_min+=1,同时x将保持不变,y往下递增;
当移到边界位置(x_max,y_max)时,表明最后一列已打印完,故y_max-=1,同时y将保持不变,x往后递减;
当移到边界位置(x_min,y_max)时,表明最后一行已打印完,故x_max-=1,同时x将保持不变,y往上递减;
当移到边界位置(x_min,y_min)时,表明第一列已打印完,故y_min-=1,同时y将保持不变,x往前递增,需注意,这一步需是已经顺时针遍历一圈后才能进行检测。
在编码时,每次min和max的变化需移至下一个边界点的到来才能进行,否则会陷入死循环导致数组溢出(具体可看代码)。
代码如下:
测试代码:
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,
例如,如果输入如下矩阵: 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.
算法描述:
以(x,y)元组作为当前打印元素的指针,当前位置加上-1,0,1分别
表示x,y坐标后退、保持不变和前进。如矩阵
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
若当前位置为(0,0),则打印1;
顺时针打印时,移动到下一个位置即x+1,y+0,故为(1,0),即打印2;
再往下,(2,0),打印3;
……
最后一个元素则是(1,2),打印10.
首先检测是否为单行单列,若是,则只需一个for循环即可解决,否则进入下一步:
从坐标(0,0)开始,x依次递增,y不变,同时,记录x,y的最大最小值x_min,x_max和y_min.y_max,然后开始移动坐标;
当移到边界位置(x_max,y_min)时,表明第一行已打印完,故x_min+=1,同时x将保持不变,y往下递增;
当移到边界位置(x_max,y_max)时,表明最后一列已打印完,故y_max-=1,同时y将保持不变,x往后递减;
当移到边界位置(x_min,y_max)时,表明最后一行已打印完,故x_max-=1,同时x将保持不变,y往上递减;
当移到边界位置(x_min,y_min)时,表明第一列已打印完,故y_min-=1,同时y将保持不变,x往前递增,需注意,这一步需是已经顺时针遍历一圈后才能进行检测。
在编码时,每次min和max的变化需移至下一个边界点的到来才能进行,否则会陷入死循环导致数组溢出(具体可看代码)。
代码如下:
class Solution { public: vector<int> printMatrix(vector<vector<int> > matrix) { vector<int> results; if (matrix.size() == 0) { return results; } int x = 0; int y = 0; //当前元素的位置 int xf = 0; int yf = 1;//xf和yf表示当前元素位置指针的方向,-1表后退,0停止,1前进 int rows = matrix.size()-1; //行 int cols = matrix.at(0).size()-1; //列 //当只有一行时 if (rows == 0) { for (int i = 0; i <= cols; i++) { results.push_back(matrix.at(0).at(i)); } return results; } //当只有一列时 if (cols == 0) { for (int i = 0; i <= rows; i++) { results.push_back(matrix.at(i).at(0)); } return results; } int x_start = 0; int y_start = 0; int x_end = rows; int y_end = cols; bool isFirst = true; int size = (rows+1)*(cols+1); //元素个数 while (results.size() < size) { results.push_back(matrix[x][y]); //记录当前元素 x += xf; //横坐标变换 y += yf; //纵坐标变化 //开始进行四个角的判断以及相关操作 if (x == x_start && y == y_end) { xf = 1; yf = 0; if (!isFirst) { y_start += 1; } } if (x == x_end && y == y_end) { xf = 0; yf = -1; x_start += 1; } if (x == x_end && y == y_start) { xf = -1; yf = 0; y_end -= 1; } if (x == x_start && y == y_start) { xf = 0; yf = 1; x_end -= 1; isFirst = false; } } return results; } };
测试代码:
int main() { vector<vector<int> > matrix; int x = 1; for (int i = 0; i < 4; i++) { vector<int> tmp; for (int j = 0; j < 1; j++) { tmp.push_back(x++); } matrix.push_back(tmp); } Solution s; vector<int> re = s.printMatrix(matrix); for (int i = 0; i < re.size(); i++) { cout << re[i] << " "; } }
相关文章推荐
- 尽快报告坏消息
- 你是如何成为 Lisp 程序员的(转)
- Centos6.5安装JDK8+tomcat8.0.22+oracle-11g
- AndroidManifest.xml——application
- AngularJS学习笔记一:简单入门
- Java:读取系统信息
- jsonp
- JS设置 按钮为可用和不可用两种状态
- CentOS下MySQL安装记录
- mini-httpd源码分析-version.h
- Java:返回当前内存信息
- 梦断代码-读书笔记三
- getview参数解释
- Python小知识
- 在python中对list求和及求积
- oracle官方文档--DBMS_SQLPA
- 《你的灯还亮着吗》阅读笔记三
- java:取屏幕大小(去掉任务栏的高度部分)
- 一切从编辑器说起:web前端代码编辑器
- Eclipse:构造函数不提示才发现