题目:
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 s, int numRows);
Example 1:
Input: s = "PAYPALISHIRING", numRows = 3 Output: "PAHNAPLSIIGYIR"
Example 2:
Input: s = "PAYPALISHIRING", numRows = 4 Output: "PINALSIGYAHRPI" Explanation: P I N A L S I G Y A H R P I
题目解释:就是将这个字符串根据输入的行数向下排列,然后走一个倒N型,向下,斜上再向下,这样排列直到字符串结束,然后按行横向输出。
解题思路: 直接找规律,输出。
s = "PAYPALISHIRING", numRows = 4 (括号里的数字代表这个字符在该字符串的位置)
P(0) | P(6) | N(12) | ||||
A(1) | L(5) | S(7) | I(11) | G(13) | ||
Y(2) | A(4) | H(8) | R(10) | |||
P(3) | I(9) |
首先可以确定的是中间斜着的行数(也就是每两个竖列之间的间隔)是gap = numRows - 2 =2
观察可以发现:
第一行和最后一行都是每隔6位取一位 通过观察 ,可以通过(numRows-1)+gap+1得到 其实就是竖着的4个(因为下标从0开始计算,所以应该减一) 加上两个斜着的(gap) 再加上另一列上的1(语言表达能力不太好,希望大家可以看的懂。。。。。) 这样可以计算出首行和尾行的间隔,将这个间隔设为k1,k1 = 6
第二行是1,5,7,11,13 间隔是 +4 +2 +4 +2 ...... 这个可以两个看作一组,4就是 k2 = k1-i*2 = k1-2 (这里的i是指行数,从0开始计算) ,2可以看作 k1 - k2
第三行是2,4,8,10 间隔是 +2 +4 +2 +4 同样,2是k2 = k1 - i*2 = k1 -4 ,4位k1-k2
验证上面的规律:
s= "PAYPALISHIRING" , numRows = 3 (括号里的数字代表这个字符在该字符串的位置)
P(0) | A(4) | H(8) | N(12) | |||
A(1) | P(3) | L(5) | S(7) | I(9) | I(11) | G(13) |
Y(2) | I(6) | R(10) |
gap = numRows - 2 =1
第一行和最后一行都是每隔4位取一位 k1 = (numRows-1)+gap+1 = 3-1+1+1 = 4
第二行是1,3,5,7,9 每次位数增加2 i = 1, +2 +2 +2 +2...... k2 = k1-i*2 = k1-2 = 4-2 = 2 后面就可以直接用 k1-k2 然后每次更新k2即可
如果不放心 ,可以另取一个numRows较大的字符串进行测试。
找到规律以后就可以直接编写代码,值得注意的是 这里会有一个边界条件,length==0或length<=numRows或numRows==1都可以直接输出,不需要进行操作。
class Solution {
public String convert(String s, int numRows) {
int length = s.length();
if(length==0||length<=numRows||numRows==1){
return s;
}
int gap = numRows-2;
String ans = "";
int k1 = numRows -1 + gap + 1;
for(int i=0;i<numRows;i++){
int location = 0;
if(i==0||i==numRows-1){
ans = ans+s.charAt(i);
location = i+k1;
while(location<length){
ans = ans+s.charAt(location);
location = location + k1;
}
}else{
ans = ans + s.charAt(i);
int k2 = k1 - i*2;
location = location + k2 + i;
while(location<length){
ans = ans + s.charAt(location);
k2 = k1 - k2;
location = k2 + location;
}
}
}
return ans;
}
}