我发现有一类题目,比如这一道题,都是属于思路好想,但是很容易编程有bug的题目。
要特别细心处理corner case。。。
这里还看到一个比较不容易出错的方法,就是把nRows个string叠加起来,然后连接起来就好 http://blog.csdn.net/errant_xia/article/details/8639920
package Level3; import java.util.Arrays; /** * ZigZag Conversion * * The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) P A H N A P L S I I G Y I R And then read line by line: "PAHNAPLSIIGYIR" Write the code that will take a string and make this conversion given a number of rows: string convert(string text, int nRows); convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR". Discuss */ public class S6 { public static void main(String[] args) { // System.out.println(convert("PAYPALISHIRING", 4)); System.out.println(convert("ABCD", 2)); } public static String convert(String s, int nRows) { if(s.length() == 0){ return s; } int nCols = s.length(); char[][] buf = new char[nRows][nCols]; for(char[] ch : buf){ Arrays.fill(ch, ' '); } int x = 0, y = 0; boolean down = true; for(int i=0; i<s.length();){ buf[x][y] = s.charAt(i); if(down) { // 往下走 if(x == nRows-1){ // 走到最底,改变方向 if(x > 0){ // 注意当只有一行时可能出现负数! x--; } y++; down = false; }else{ // 往下走 x++; } i++; }else{ // 往右上走 if(x == 0){ // 仅仅改变方向,不前进i down = true; } if(x >=1){ // 继续往右上方走 x--; y++; i++; } } } String ret = ""; for(int i=0; i<nRows; i++){ for(int j=0; j<nCols; j++){ if(buf[i][j] != ' '){ ret += buf[i][j]; } } } return ret; } }
Again:
public static String convert(String s, int nRows) { if(nRows<=1 || s.length()<2){ return s; } String[] ss = new String[nRows]; // 用来存储每一行 Arrays.fill(ss, ""); int nGroup = 2 * (nRows-1); // 每nGroup,zigzag pattern就会重复一遍 for(int i=0; i<s.length(); i++){ // 推导出的公式 /* eg: nRows=4, nGroup=6 i%group: 0,1,2,3,4,5 nRows-1-(i%nGroup): 3,2,1,0,-1,-2 abs(): 3,2,1,0,1,2 total: 0,1,2,3,2,1 */ ss[nRows-1-Math.abs(nRows-1-(i%nGroup))] += s.charAt(i); } String ret = ""; for(String str : ss){ ret += str; } return ret; }
两个规律:
1 两个zigzag之间间距为2*nRows-2
2 每个zigzag中间(在j和j+interval之间)位置为j+interval-2*i
public String convert(String s, int nRows) { int len = s.length(); int interval = 2 * nRows - 2; // interval for zigzag if(len<=1 || nRows<=1) { return s; } String ret = ""; for(int i=0; i<nRows; i++) { // row-wise for(int j=i; j<len; j+=interval) { // next zigzag ret += s.charAt(j); int mid = j + interval - 2 * i; // middle value in zigzag // ignore first and last row if(i!=0 && i!=nRows-1 && mid >= 0 && mid < len) { ret += s.charAt(mid); } } } return ret; }