题目:Z字形转换
将字符串 "PAYPALISHIRING"
以Z字形排列成给定的行数:
P A H N
A P L S I I G
Y I R
之后从左往右,逐行读取字符:"PAHNAPLSIIGYIR"
实现一个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
给一个字符串长点的,numRows为5,我们来看看规律
字符串:"0123456789ABCDEFGH",其分布为
0 8 G
1 7 9 F H
2 6 A E
3 5 B D
4 C
转化结果是:08G179FH26AEI35BD44CC
等差数列的通项公式
从第0,4行来看,满足等差数列,差值d=8,所以0->8->G,4->C
从第1,2,3行来看,在满列的情况下,1->9->H,2->A,3->B同样满足等差数列
所以需要考虑在不是首行也不是最后一行的情况下,在满足等差数列的两个值之间都多了一个值,这个值又满足怎么样的一种规律呢
在第1行,1和9之间多了个7,9和H之间多了个F(H的值是17,G的值是15)
在第2行,2和A之间多了个6,
在第3行,3和B之间多了个5,
仔细看一下,其中是有规律的,两个列依旧差值是d=8,可以看出满足j+d-2*i;(其中j是当前列的前一个值,比如7时,j=1,F时,j=9,因为我们是以等差数列的行数来循环的;i是当前的行数)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Solution
{
class Program
{
static void Main(string[] args)
{
string s = "0123456789ABCDEFGHI";
string result = Convert(s, 5);
Console.WriteLine(result);
Console.ReadKey();
}
static string Convert(string s, int numRows)
{
int len = s.Length;
if(len==0||numRows==1)
return s;
//存放新的字符串
StringBuilder sb = new StringBuilder();
//等差数列的差值
int d = 2 * numRows - 2;
//从首行遍历到最后一行
for (int i = 0; i < numRows; i++)
{
//差值是d
for (int j = i; j < len; j += d)
{
sb.Append(s[j]);
//处理不是首行和最后一行,加入两个满列之间的值
if (i != 0 && i != numRows - 1 && j + d - 2 * i < len)
{
sb.Append(s[j + d - 2 * i]);
}
}
}
return sb.ToString();
}
}
}