[经典算法]优雅实现顺时针打印矩阵
来源:互联网 发布:金冠网络中介平台 编辑:程序博客网 时间:2024/05/19 16:22
记得这是我在Google面试的时候,被问到的一个问题。关于顺时针打印矩阵问题描述,大家可以搜索下题目,大致信息如下:
给定一个m*n的矩阵,要求,从外层顺时针打印一直到打印完所有元素,
如:
1、2*2矩阵
1 2
3 4
输出:1 2 4 3
2、3*4矩阵
1 2 3 4
5 6 7 8
9 1 2 3
输出:1 2 3 4 8 3 2 1 9 5 6 7
乍一看,这道题挺简单,尤其在面试时,以最快速度写出代码为目标,直接用4个for循环手写代码。但在写的过程中,发现要注意的边界问题很多,但最后还是磕磕绊绊写完了。之后没再考虑了,直到最近偶然看到网上的一些解法,遂觉得是否有更优雅的写法。经过思考,其实只需要考虑矩阵的四个坐标,通过四个坐标的边界来控制即可。每次循环完最外层,四个边界缩小一层即可。最后再通过是否有打印输出作为最外层循环结束条件即可。这样一来,只通过一个for循环搞定,从而以最优雅的方法完美解决该问题。同时,最少的循环,避免复杂的边界判断。
废话不多说,直接上代码,欢迎拍砖。
不用考虑打印方向,只通过一个for循环,优雅完成顺时针打印任务。尽可能少的判断边界条件,从而减少错误概率。
给定一个m*n的矩阵,要求,从外层顺时针打印一直到打印完所有元素,
如:
1、2*2矩阵
1 2
3 4
输出:1 2 4 3
2、3*4矩阵
1 2 3 4
5 6 7 8
9 1 2 3
输出:1 2 3 4 8 3 2 1 9 5 6 7
乍一看,这道题挺简单,尤其在面试时,以最快速度写出代码为目标,直接用4个for循环手写代码。但在写的过程中,发现要注意的边界问题很多,但最后还是磕磕绊绊写完了。之后没再考虑了,直到最近偶然看到网上的一些解法,遂觉得是否有更优雅的写法。经过思考,其实只需要考虑矩阵的四个坐标,通过四个坐标的边界来控制即可。每次循环完最外层,四个边界缩小一层即可。最后再通过是否有打印输出作为最外层循环结束条件即可。这样一来,只通过一个for循环搞定,从而以最优雅的方法完美解决该问题。同时,最少的循环,避免复杂的边界判断。
废话不多说,直接上代码,欢迎拍砖。
- public class Test {
- private boolean valid(int cc, int m, int n){
- if( cc >= m && cc <= n ){
- return true;
- }
- return false;
- }
- public void print(int m, int n, int a[][], boolean visited[][]){
- int offsetX[] = new int[]{0,1,0,-1};
- int offsetY[] = new int[]{1, 0, -1, 0};
- int sX = 0, eX = n - 1;
- int sY = 0, eY = m - 1;
- boolean flag = false;
- do{
- if( sX > eX || sY > eY ){
- break;
- }
- int xTmp = sX;
- int yTmp = sY;
- for( int ii = 0; ii < offsetX.length;){
- if( valid( xTmp, sY, eY) && valid(yTmp, sX, eX) && !visited[xTmp][yTmp]){
- System.out.print(a[xTmp][yTmp]+"\t");
- visited[xTmp][yTmp] = true;
- flag = true;
- }
- if( valid(xTmp + offsetX[ii], sY, eY) && valid(yTmp + offsetY[ii], sX, eX) ){
- xTmp += offsetX[ii];
- yTmp += offsetY[ii];
- }else{
- ii++;
- }
- }
- sX++;
- eX--;
- sY++;
- eY--;
- }while( flag );
- }
- public static void main(String[] args) {
- int a[][];
- int m = (int)(Math.random() * 5)+1;
- int n = (int)(Math.random() * 5)+1;
- // m = 10;
- // n = 1;
- a = new int[m][n];
- boolean visited[][] = new boolean[m][n];
- System.out.println( m + " * " + n);
- for( int i = 0; i < m; i++ ){
- for( int j = 0; j < n; j++ ){
- int tmp = (int)(Math.random() * 10);
- a[i][j] = tmp;
- visited[i][j] = false;
- System.out.print(tmp+"\t");
- }
- System.out.println();
- }
- System.out.println();
- System.out.println("顺时针打印:");
- Test t = new Test();
- t.print(m, n, a, visited);
- }
- }
不用考虑打印方向,只通过一个for循环,优雅完成顺时针打印任务。尽可能少的判断边界条件,从而减少错误概率。
0 0
- [经典算法]优雅实现顺时针打印矩阵
- 经典算法——顺时针打印矩阵
- 顺时针打印矩阵[算法]
- [算法学习]顺时针打印矩阵
- 算法题目--顺时针打印矩阵
- 算法题目---顺时针打印矩阵
- 算法题/顺时针打印矩阵
- 顺时针打印矩阵java实现
- 面试算法(十九)顺时针打印矩阵
- 每天一个算法之顺时针打印矩阵
- 顺时针打印矩阵 -- 漫漫算法路 刷题篇
- 顺时针打印矩阵 (JAVA实现)
- 顺时针打印矩阵 (JAVA实现)
- 顺时针打印矩阵(Java实现)
- 顺时针打印矩阵
- 顺时针打印矩阵
- 顺时针打印矩阵
- 顺时针打印矩阵
- 寻找数组中的缺失元素
- 字符串转为数字。字符串转为数组。
- Twitter的分布式自增ID算法snowflake (Java版)
- Jquery 笔记
- 原生JS如何更准确的获取CSS样式
- [经典算法]优雅实现顺时针打印矩阵
- github常见操作和常见错误!错误提示:fatal: remote origin already exists.
- Java的JDBC事务详解
- visio 2013 连接线使用技巧
- Android二维码扫描开发:实现思路与原理
- css的hover不生效
- 获取服务器json数据并解析显示listview上
- Improved Image Captioning via Policy Gradient optimization of SPIDEr
- mysql数据库引擎比较