比方提供如下矩阵:java
按照以下顺序打印出来:优化
1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10spa
这道题直接写也没问题,就是特别容易出错,稍不留意就写错,并且这类题型我想要一种普适性的解法。指针
我想到的一种方法就是一圈一圈打印,从外到内,咱们肯定一个矩形,一般经过左上角的坐标和右下角的坐标便可,即(tR,tC)和(dR,dC),咱们先写出打印一圈的方法,而后循环调用,若是咱们发现左上角的坐标跑到了右下角坐标的右边或者下边,整个过程就中止,这样额外的空间复杂度是O(1)。No bibi,show me the code.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--; } } } }
给出一个数字,比方是4,直接生成以下矩阵:blog
思路和上一个相似,只是稍微改一下便可:get
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--; } } } }
一个起始点在左上角,和之前同样,顺时针走,另外一个起始点在右下角,也是顺时针走,别人走过的,就不能重复走了。it
比方class
打印出:1 2 3 4 import
打印出: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<Integer> list1 = new LinkedList<>(); List<Integer> 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<Integer> list1 = new LinkedList<>(); List<Integer> 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) + " "); } } } }