博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[算法]循环打印矩阵,蛇形矩阵专题
阅读量:6585 次
发布时间:2019-06-24

本文共 11428 字,大约阅读时间需要 38 分钟。

1. 循环打印矩阵

比方提供以下矩阵:

按照如下顺序打印出来:

1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10

这道题直接写也没问题,就是特别容易出错,稍不留意就写错,而且这类题型我想要一种普适性的解法。

我想到的一种方法就是一圈一圈打印,从外到内,我们确定一个矩形,通常通过左上角的坐标和右下角的坐标即可,即(tR,tC)和(dR,dC),我们先写出打印一圈的方法,然后循环调用,如果我们发现左上角的坐标跑到了右下角坐标的右边或者下边,整个过程就停止,这样额外的空间复杂度是O(1)。No bibi,show me the code.

package com.darrenchan;/** * 转圈打印矩阵 * @author Think * */public class SheXingPrint2 {    public static void main(String[] args) {        int[][] m = new int[][]{
{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}}; int tR = 0, tC = 0, dR = 0, dC = 3; while(tR <= dR && tC <= dC){ printEdge(m, tR++, tC++, dR--, dC--); } } public static void printEdge(int[][] m, int tR, int tC, int dR, int dC){ if(tR == dR){ for (int i = tC; i <= dC; i++) { System.out.print(m[tR][i] + " "); } }else if(tC == dC){ for (int i = tR; i <= dR; i++) { System.out.print(m[i][tC] + " "); } }else{ int curRow = tR; int curCol = tC; while(curCol != dC){ System.out.print(m[tR][curCol] + " "); curCol++; } while(curRow != dR){ System.out.print(m[curRow][dC] + " "); curRow++; } while(curCol != tC){ System.out.print(m[dR][curCol] + " "); curCol--; } while(curRow != tR){ System.out.print(m[curRow][tC] + " "); curRow--; } } }}

2. 蛇形矩阵

给出一个数字,比方是4,直接生成如下矩阵:

思路和上一个类似,只是稍微改一下即可:

package com.darrenchan;/** * 打印蛇形矩阵 * @author Think * */public class SheXingPrint3 {    public static int num = 1;    public static void main(String[] args) {        //给出多大的数字,就构造多大的矩阵        int length = 4;        int[][] m = new int[length][length];        int tR = 0, tC = 0, dR = m.length - 1, dC = m[0].length - 1;        while (tR <= dR && tC <= dC) {            generateEdge(m, tR++, tC++, dR--, dC--);        }                for (int i = 0; i < m.length; i++) {            for (int j = 0; j < m[i].length; j++) {                System.out.print(m[i][j] + "\t");            }            System.out.println();        }    }    public static void generateEdge(int[][] m, int tR, int tC, int dR, int dC) {        if(tR == dR){
//处理length为奇数,最中间一个元素 m[tR][tC] = num; }else{ int curRow = tR; int curCol = tC; while(curCol != dC){ m[tR][curCol] = num; num++; curCol++; } while(curRow != dR){ m[curRow][dC] = num; num++; curRow++; } while(curCol != tC){ m[dR][curCol] = num; num++; curCol--; } while(curRow != tR){ m[curRow][tC] = num; num++; curRow--; } } }}

 

3. 双循环打印矩阵

一个起始点在左上角,和以前一样,顺时针走,另一个起始点在右下角,也是顺时针走,别人走过的,就不能重复走了。

比方

打印出:1 2 3 4 

打印出:1 2 3 6 5 4 7 8 9 

打印出:1 2 3 4 8 12 11 10 7 6 5 9 13 14 15 16 

这道题的思路其实和上面第一个差不多,我还是采用的一圈一圈打印的思路,只不过原来一个指针打印一圈转4个方向,现在有两个指针,每个转2个方向,第一次转两个方向,第二次转另两个方向,依次类推。

其实这道题还可以进一步优化,因为两个指针完全关于矩阵中心点对称,所以确定一个,另一个就确定了。这里需要一个矩阵来记录该点是否已经走过。

代码如下:

package com.darrenchan;import java.util.LinkedList;import java.util.List;/** * 双蛇形打印 * @author Think * */public class SheXingPrint4 {    public static int num = 1;    public static void main(String[] args) {        //给出多大的数字,就构造多大的矩阵        int length = 5;        int[][] m = new int[length][length];        int temp = 1;        for (int i = 0; i < m.length; i++) {            for (int j = 0; j < m[i].length; j++) {                m[i][j] = temp++;            }        }        int[][] visited = new int[m.length][m[0].length];//0是没有访问过,1是访问过                List
list1 = new LinkedList<>(); List
list2 = new LinkedList<>(); int tr = 0; int tc = 0; int dr = m.length - 1; int dc = m[0].length - 1; int count = 1; while(tr <= dr && tc <= dc){ if(count % 2 == 1){ int curRow1 = tr; int curCol1 = tc; int curRow2 = dr; int curCol2 = dc; while(curCol1 != dc && curCol2 != tc){ if(visited[curRow1][curCol1] == 0 && visited[curRow2][curCol2] == 0){ visited[curRow1][curCol1] = 1; list1.add(m[curRow1][curCol1]); curCol1++; visited[curRow2][curCol2] = 1; list2.add(0, m[curRow2][curCol2]); curCol2--; }else{ break; } } while(curRow1 != dr && curRow2 != tr){ if(visited[curRow1][curCol1] == 0 && visited[curRow2][curCol2] == 0){ visited[curRow1][curCol1] = 1; list1.add(m[curRow1][curCol1]); curRow1++; visited[curRow2][curCol2] = 1; list2.add(0, m[curRow2][curCol2]); curRow2--; }else{ break; } } } if(count % 2 == 0){ int curRow1 = dr; int curCol1 = dc; int curRow2 = tr; int curCol2 = tc; while(curCol1 != tc && curCol2 != dc){ if(visited[curRow1][curCol1] == 0 && visited[curRow2][curCol2] == 0){ visited[curRow1][curCol1] = 1; list1.add(m[curRow1][curCol1]); curCol1--; visited[curRow2][curCol2] = 1; list2.add(0, m[curRow2][curCol2]); curCol2++; }else{ break; } } while(curRow1 != tr && curRow2 != dr){ if(visited[curRow1][curCol1] == 0 && visited[curRow2][curCol2] == 0){ visited[curRow1][curCol1] = 1; list1.add(m[curRow1][curCol1]); curRow1--; visited[curRow2][curCol2] = 1; list2.add(0, m[curRow2][curCol2]); curRow2++; }else{ break; } } } count++; tr++; tc++; dr--; dc--; } System.out.println(list1); System.out.println(list2); if(length % 2 == 0){ for (int i = 0; i < list1.size(); i++) { System.out.print(list1.get(i) + " "); } for (int i = 0; i < list2.size(); i++) { System.out.print(list2.get(i) + " "); } }else{ for (int i = 0; i < list1.size(); i++) { System.out.print(list1.get(i) + " "); } System.out.print(m[(length - 1) / 2][(length - 1) / 2] + " "); for (int i = 0; i < list2.size(); i++) { System.out.print(list2.get(i) + " "); } } }}

优化之后的代码如下:

package com.darrenchan;import java.util.LinkedList;import java.util.List;/** * 双蛇形打印(优化版) * @author Think * */public class SheXingPrint5 {    public static int num = 1;    public static void main(String[] args) {        //给出多大的数字,就构造多大的矩阵        int length = 4;        int[][] m = new int[length][length];        int temp = 1;        for (int i = 0; i < m.length; i++) {            for (int j = 0; j < m[i].length; j++) {                m[i][j] = temp++;            }        }        int[][] visited = new int[m.length][m[0].length];//0是没有访问过,1是访问过                List
list1 = new LinkedList<>(); List
list2 = new LinkedList<>(); int tr = 0; int tc = 0; int dr = m.length - 1; int dc = m[0].length - 1; int count = 1; while(tr <= dr && tc <= dc){ if(count % 2 == 1){ int curRow1 = tr; int curCol1 = tc; while(curCol1 != dc){ if(visited[curRow1][curCol1] == 0){ visited[curRow1][curCol1] = 1; list1.add(m[curRow1][curCol1]); visited[length - 1 - curRow1][length - 1 - curCol1] = 1; list2.add(0, m[length - 1 - curRow1][length - 1 - curCol1]); curCol1++; }else{ break; } } while(curRow1 != dr){ if(visited[curRow1][curCol1] == 0){ visited[curRow1][curCol1] = 1; list1.add(m[curRow1][curCol1]); visited[length - 1 - curRow1][length - 1 - curCol1] = 1; list2.add(0, m[length - 1 - curRow1][length - 1 - curCol1]); curRow1++; }else{ break; } } } if(count % 2 == 0){ int curRow1 = dr; int curCol1 = dc; while(curCol1 != tc){ if(visited[curRow1][curCol1] == 0){ visited[curRow1][curCol1] = 1; list1.add(m[curRow1][curCol1]); visited[length - 1 - curRow1][length - 1 - curCol1] = 1; list2.add(0, m[length - 1 - curRow1][length - 1 - curCol1]); curCol1--; }else{ break; } } while(curRow1 != tr){ if(visited[curRow1][curCol1] == 0){ visited[curRow1][curCol1] = 1; list1.add(m[curRow1][curCol1]); visited[length - 1 - curRow1][length - 1 - curCol1] = 1; list2.add(0, m[length - 1 - curRow1][length - 1 - curCol1]); curRow1--; }else{ break; } } } count++; tr++; tc++; dr--; dc--; } /** * 打印 */ System.out.println(list1); System.out.println(list2); if(length % 2 == 0){ for (int i = 0; i < list1.size(); i++) { System.out.print(list1.get(i) + " "); } for (int i = 0; i < list2.size(); i++) { System.out.print(list2.get(i) + " "); } }else{ for (int i = 0; i < list1.size(); i++) { System.out.print(list1.get(i) + " "); } System.out.print(m[(length - 1) / 2][(length - 1) / 2] + " "); for (int i = 0; i < list2.size(); i++) { System.out.print(list2.get(i) + " "); } } }}

 

转载地址:http://xtxno.baihongyu.com/

你可能感兴趣的文章
UUID为36位
查看>>
程序员的经验
查看>>
CodeForces-1167E-Range Deleting
查看>>
兼容多个版本程序集的web.config配置
查看>>
JS 之如何在插入元素时插在原有元素的前面而不是末尾
查看>>
vim编辑器-多行加注释与去注释
查看>>
CodeForces 197A Plate Game :轮流在矩形中放圆,先放不下者输 :博弈+思维
查看>>
java finally块执行时机分析
查看>>
小强的HTML5移动开发之路(35)——jQuery中的过滤器详解
查看>>
string中c_str()、data()、copy(p,n)函数的用法+strstr()函数用法
查看>>
Linux里的lsb_release命令用来查看当前系统的发行版信 息
查看>>
spring.http.multipart.maxFileSize提示无效报错问题处理
查看>>
Docker | 删除 image 失败的一种情况
查看>>
hibernate框架内容整理 学习
查看>>
day6 字符串
查看>>
day5 用户交互 input用法
查看>>
JMeter5.0 边界提取器使用
查看>>
CF Fox And Names (拓扑排序)
查看>>
CF Sea and Islands
查看>>
Oracle的条件in中包含NULL时的处理
查看>>