一、Z字形字符串
共两种方法:
一:模拟法
最开始能想到的是摆一个矩阵,然后将字符串中一个个字符摆到矩阵中合适的位置。最后按行收集。
这样做的缺点是按行收集的时候需要过滤空格。
该方法的升级,可以知道每个字符会放到哪一行,直接将该字符收集到指定的行。
二:找规律,计算
这个建议开始这个具体的例子算一下,总结规律。还有一点就是,先抓住第一行和最后一行的规律,然后在总结中间行的规律。感觉方法二比方法一好,想明白了之后,得到的愉悦感更强。
最近感觉TDD是个好东西,由测试驱动,笔者更有兴趣完成功能。
package com.ceh.leetcode.string;
import org.junit.Assert;
import org.junit.Test;
class Solution {
public String convert(String s, int numRows) {
if (numRows < 2) {
return s;
}
StringBuilder str[] = new StringBuilder[numRows];
for (int i = 0; i < numRows; i++) {
str[i] = new StringBuilder();
}
int index = 0;
int row = 0;
int flag = -1;
while(index < s.length()) {
str[row].append(s.charAt(index++));
if(row == 0 || row == numRows-1) {
flag = -1 * flag;
}
row = row + flag;
}
for (int i = 1; i < numRows; i++) {
str[0].append(str[i]);
}
return str[0].toString();
}
public String convert2(String s, int numRows) {
if (numRows < 2) {
return s;
}
StringBuilder result = new StringBuilder();
for (int i = 0; i < numRows; i++) {
if (i == 0) {
for (int j = 0; (numRows - 1) * j * 2 < s.length(); j++) {
result.append(s.charAt((numRows - 1) * j * 2));
}
} else if (i == numRows - 1) {
for (int j = 1; (numRows - 1) * (j * 2 - 1) < s.length(); j++) {
result.append(s.charAt((numRows - 1) * (j * 2 - 1)));
}
} else {
for (int j = 0; ; j++) {
if((numRows - 1) * j * 2 + i < s.length()) {
result.append(s.charAt((numRows - 1) * j * 2 + i));
} else {
break;
}
if((numRows - 1) * (j * 2 + 1) + numRows - 1 - i < s.length()) {
result.append(s.charAt((numRows - 1) * (j * 2 + 1) + numRows - 1 - i));
} else {
break;
}
}
}
}
return result.toString();
}
}
public class Leetcode006 {
private Solution solution = new Solution();
@Test
public void test01() {
String s = "PAYPALISHIRING";
int numRows = 3;
Assert.assertEquals("PAHNAPLSIIGYIR", solution.convert(s, numRows));
}
@Test
public void test02() {
String s = "PAYPALISHIRING";
int numRows = 3;
Assert.assertEquals("PAHNAPLSIIGYIR", solution.convert2(s, numRows));
}
}