比方提供如下矩陣: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) + " "); } } } }