原题目:
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".
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 A P L S I I G Y I RAnd 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"
.
给定一个字符串,并给定特定的行号,输出该字符串的之字打印结果,按行输出。
算法分析:
题目要求按之字型排列数组,并进行输出,4行之字形的排列形状如下所示:
0
6
12
1 5 7 11 13
2 4 8 10 14
3 9 15
最后输出字符为0612157111324810143915
算法1:
将这个排列放入一个二维矩阵中,然后将矩阵按列从上到下,再向右上依次输出
0 | 6 | 12 | ||||
1 | 5 | 7 | 11 | 13 | ||
2 | 4 | 8 | 10 | 14 | ||
3 | 9 | 15 |
算法2:
对于以上的字符排列,可以发现以下规律:
(1)第1行和最后一行的每个字符间隔为2*numRows - 2(以4行为例,0——6——12间隔为 6,所以2*4-2 = 6)
(2)中间行的间隔是周期性的,第i行的间隔是: 2*numRows-2–2*i, 2*i, 2*numRows-2–2*i, 2*i, 2*numRows-2–2*i, 2*i, …
遇到问题及解决方案:
1.给字符串赋空值。当声明一个字符串时,不应该声明为null,这样在输出的字符串的开头会包含null,而应该生成为"",这样就不会出现null字符
String
resultString
=
""
;
//此处不要将resultSring 和tmp两个字符串初值设为null,这样输出字符串前会有null出现
String tmp = ""; //而应当直接赋值一个""
2.char型的默认值为空,即\u0000或'',但不能用null来判断,用null无法判断是否为空字符。
if
( matrix[m][n] != ' '){ 或
if
( matrix[m][n] !=
null
){
无法判断空格
无法判断空格
所以在判断矩阵是否为空时,应该用\u0000来去除空字符。
if( matrix[m][n] != '\u0000'){
LeetCode提交源码:
算法1:
public String convert(String s, int numRows){
if(s.length() <= 0 || numRows <= 0){
return "";
}
if(numRows == 1){
return s;
}
String resultString = ""; //此处不要将resultSring 和tmp两个字符串初值设为null,这样输出字符串前会有null出现
String tmp = ""; //而应当直接赋值一个""
char[] arr1 = s.toCharArray();
char[][] matrix = new char[numRows][300];
if(numRows == 2){
for(int i = 0; 2*i < arr1.length; i++){
tmp += arr1[2*i];
}
for(int i = 0; 2*i+1 < arr1.length; i++){
//tmp += arr1[2*i];
tmp += arr1[2*i+1];
}
resultString = tmp;
}
System.out.println("length= " + s.length());
if(numRows >= 3){
int i = 0;
int j = 0;
// int len = 0;
// int r = numRows;
/*
将字符放入二维数组中
*/
for(int k = 0; k < arr1.length;){
while(i < numRows){
matrix[i][j] = arr1[k];
//len++;
i++;
k++;
if(k >= arr1.length)
break;
}
if(k >= arr1.length)
break;
if(i == numRows){
i = i-2;
j++;
while(i > 0){
matrix[i][j] = arr1[k];
i--;
j++;
k++;
if(k >= arr1.length)
break;
}
}
}
/*
从二维数组中取出字符,去除空格
重要:char型的默认值为空,\u0000,但不能用null判断,所以在判断矩阵是否为空时,不能用户
' ' 或" "或null,而应该用\u0000来去除空字符。
*/
for(int m = 0; m < numRows; m++){
for(int n = 0; n < 300; n++){
if( matrix[m][n] != '\u0000'){ //重要!!!
tmp += matrix[m][n];
}
}
}
resultString = tmp;
}
return resultString;
}
算法2:
public String convert(String s, int numRows){
if(numRows == 1)
return s;
int len = s.length();
// int k = 0;
int interval = numRows *2-2; //每行字符的间隔
String resultString = "";
char[] array = s.toCharArray();
for(int j = 0; j < len;j+=interval){
resultString += array[j];
}
for(int i = 1; i < numRows - 1; i++){
int inter = (i<<1); //inter = 2*i;
for(int j = i; j < len; j+=inter){
resultString += array[j];
inter = interval - inter; //2numRows-2-2i
}
}
for(int j = numRows - 1; j < len; j += interval){ //处理最后一行
resultString += array[j];
}
return resultString;
}
完整运行程序:
/**************************************************************
* Copyright (c) 2016
* All rights reserved.
* 版 本 号:v1.0
* 题目描述: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".
* 给定一个字符串,并给定特定的行号,输出该字符串的之字打印结果,按行输出
* 输入描述:请输入一个字符串:
* 0123456789abcdef
* 请输入之字型的行数:
* 4
* 程序输出:算法1输出的字符串为:
* length= 16
* 06c157bd248ae39f
* 算法2输出的字符串为:
* 06c157bd248ae39f
* 问题分析:1.给字符串赋空值。当声明一个字符串时,不应该声明为null,这样在输出的字符串的开头会包含null,
* 而应该生成为"",这样就不会出现null字符
* 2.char型的默认值为空,即\u0000或'',但不能用null来判断,用null无法判断是否为空字符。
* 算法描述:算法1:定义一个二维字符数组,将之字形的排列放入数组中,再将数组中的字符按从上到下,从左下到右上的顺序进行输出。
* 算法2:总结规律
* (1)第1行和最后一行的每个字符间隔为2*numRows - 2(以4行为例,0——6——12间隔为 6,所以2*4-2 = 6)
* (2)中间行的间隔是周期性的,第i行的间隔是: 2*numRows-2–2*i, 2*i, 2*numRows-2–2*i, 2*i, 2*numRows-2–2*i, 2*i, …
* 完成时间:2016-11-14
***************************************************************/
package org.GuoGuoFighting.LeetCode06;
import java.util.Scanner;
class SolutionMethod1{
public String convert(String s, int numRows){
if(s.length() <= 0 || numRows <= 0){
return "";
}
if(numRows == 1){
return s;
}
String resultString = ""; //此处不要将resultSring 和tmp两个字符串初值设为null,这样输出字符串前会有null出现
String tmp = ""; //而应当直接赋值一个""
char[] arr1 = s.toCharArray();
char[][] matrix = new char[numRows][300];
if(numRows == 2){
for(int i = 0; 2*i < arr1.length; i++){
tmp += arr1[2*i];
}
for(int i = 0; 2*i+1 < arr1.length; i++){
//tmp += arr1[2*i];
tmp += arr1[2*i+1];
}
resultString = tmp;
}
System.out.println("length= " + s.length());
if(numRows >= 3){
int i = 0;
int j = 0;
// int len = 0;
// int r = numRows;
/*
将字符放入二维数组中
*/
for(int k = 0; k < arr1.length;){
while(i < numRows){
matrix[i][j] = arr1[k];
//len++;
i++;
k++;
if(k >= arr1.length)
break;
}
if(k >= arr1.length)
break;
if(i == numRows){
i = i-2;
j++;
while(i > 0){
matrix[i][j] = arr1[k];
i--;
j++;
k++;
if(k >= arr1.length)
break;
}
}
}
/*
从二维数组中取出字符,去除空格
重要:char型的默认值为空,\u0000,但不能用null判断,所以在判断矩阵是否为空时,不能用户
' ' 或" "或null,而应该用\u0000来去除空字符。
*/
for(int m = 0; m < numRows; m++){
for(int n = 0; n < 300; n++){
if( matrix[m][n] != '\u0000'){ //重要!!!
tmp += matrix[m][n];
}
}
}
resultString = tmp;
}
return resultString;
}
}
class SolutionMethod2{
public String convert(String s, int numRows){
if(numRows == 1)
return s;
int len = s.length();
// int k = 0;
int interval = numRows *2-2; //每行字符的间隔
String resultString = "";
char[] array = s.toCharArray();
for(int j = 0; j < len;j+=interval){
resultString += array[j];
}
for(int i = 1; i < numRows - 1; i++){
int inter = (i<<1); //inter = 2*i;
for(int j = i; j < len; j+=inter){
resultString += array[j];
inter = interval - inter; //2numRows-2-2i
}
}
for(int j = numRows - 1; j < len; j += interval){ //处理最后一行
resultString += array[j];
}
return resultString;
}
}
public class ZigZagConversion {
public static void main(String[] args){
System.out.println("请输入一个字符串:");
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();
System.out.println("请输入之字型的行数:");
int rows = scanner.nextInt();
scanner.close();
SolutionMethod1 solution1 = new SolutionMethod1();
System.out.println("算法1输出的字符串为:");
System.out.println(solution1.convert(str, rows));
SolutionMethod2 solution2 = new SolutionMethod2();
System.out.println("算法2输出的字符串为:");
System.out.println(solution2.convert(str, rows));
}
}
程序运行结果: