字符串"ZXYZXLISHIRING"写成3行的Z字形的样式如下:
Z X H N X Z L S I I G Y I R
按行读这个Z字形图案应该是 "ZXHNXZLSIIGYIR"
请编写代码完成将字符串转化为指定行数的Z字形字符串:
0 4 8
1 3 5 7 9
2 6 10
可以发现 当行数为3的时候 每4个数组成一个周期
行数为nRows的时候 周期t= 2*nRows-2
[0,nRows-1) 向下 [nRows,t) 向上
初始化一个 nRows 行的vector 依次将string中的每一个放入,在合并。
class Solution {
public:
string convert(string s, int nRows) {
if (nRows <= 1) return s;
int t = nRows + nRows - 2; //求出循环周期
string res="";
vector<string> m(nRows, res);
for (int i = 0; i < s.length(); i++)
{
int a = i%t;
if (a < nRows) //往下走
m[a]+=s[i];
else //往上走
m[t - a ] += s[i];
}
for (int i = 0; i < nRows; i++)
res += m[i]; //合并
return res;
}
}; // 定义nRows长度的stringbuffer数组,存放每一行的结果 // 先从0~nRows,再从nRows-2~0
public class Solution {
public String convert(String s, int nRows) {
if(s == null || s.length() == 0 || nRows <= 1)
return s;
StringBuffer[] sb = new StringBuffer[nRows];
for(int i = 0; i < sb.length; i++)
sb[i] = new StringBuffer();
int len = s.length();
int i = 0;
while(i < len){
for(int j = 0; j < nRows && i < len; j++)
sb[j].append(s.charAt(i++));
for(int j = nRows - 2; j > 0 && i < len; j--)
sb[j].append(s.charAt(i++));
}
for(int j = 1; j < nRows; j++)
sb[0].append(sb[j]);
return sb[0].toString();
}
}
string convert(string s, int nRows) {
// 计算下标可得
// 第一行下标之间的间隔为2*nRows-2,从0开始
// 第二行下标由第一行下标分别-1和+1得到(除去<0和>字符串长度的)
// 第三行下表由第一行下标分别-2和+2得到(除去<0和>字符串长度的)
// 直到第nRows行
if (nRows <= 1) return s;
string res = ""; // 必须初始化为""
int lenS = s.length();
// 第一行
for (int i = 0; i < lenS; i += 2 * nRows - 2) res += s[i];
// 中间行
for (int row = 1; row < nRows - 1; row ++) {
res += s[row];
for (int i = 2 * nRows - 2; i - row < lenS; i += 2 * nRows - 2) {
if (i - row >= nRows) res += s[i - row];
if (i + row < lenS) res += s[i + row];
}
}
// 最后一行,因为最后一行不能由第一行加和减得到,会重复,所以单独拿出来
for (int i = nRows - 1; i < lenS; i += 2 * nRows - 2) res += s[i];
return res;
}
//这个题目搞循环控制搞了1个小时。。。**,感觉要爆炸。
这个是Z字形来走的
A E I
B D F H
C G
这样来弄,只有第一行和最后一行的都是nRows*2 -2;
中间的行要分上下两个方向来走
如果从下往上走,那么中间的间隔为count + size - 2 * i; 然后另外一种情况的间隔为size。
中间的一些变量请参考代码。 class Solution {
public:
string convert(string s, int nRows) {
if(s == "" || s.size() <= 1 || nRows <= 1) return s;
string ans = "";
int size = nRows*2 -2;
for(int i = 0 ; i != nRows ; ++i)
{
int count = i;
while(count < s.size())
{
ans += s[count];
if(i > 0 && i < (nRows-1))
{
int tmp = count + size - 2 * i;
if(tmp < s.size()) ans += s[tmp];
}
count = count + size;
}
}
return ans;
}
};
/*举例子:1-20的数字,nRows = 5,输出结果应当为1 9 17 2 8 10 16 18 3 7 11 15 19 4 6 12 14 20 5 13
1 9 17
2 8 10 16 18
3 7 11 15 19
4 6 12 14 20
5 13
对于第一行和最后一行,每个数之间间隔2*nRows - 2
对于中间行而言:
第二行:(1)2,10,18之间仍然间隔2*nRows - 2
(2)2,8之间间隔6,可表示为2*nRows - 2 - 2,同理对于10和16也是
第三行:(1)3,11,19之间间隔2*nRows - 2
(2)3,7之间间隔4,可表示为2*nRows - 2 - 2*2,同理对于11和15也是
第三行:(1)4,12,20之间间隔2*nRows - 2
(2)4,6之间间隔2,可表示为2*nRows - 2 - 2*3,同理对于12和14也是
通过发现以上规律,我们可以得到解题思路:
对于第一行和最后一行,通过简单的循环单独处理,一个个将字符加入到结果集中
对于中间行,每循环一次将每两个字符加入到结果集中,但是要判断字符是否存在越界访问情况
如上面例子第二行2和8,10和16,对于18,其加上间隔2*nRows - 2 - 2*2后字符访问越界
*/
public class Solution {
public String convert(String s, int nRows) {
if(s == null || s.length() == 0 || nRows <= 1)
return s;
int len = s.length();
//使用StringBuffer运行效率更高
StringBuffer res = new StringBuffer();
//单独处理第一行
for(int i = 0; i < len; i += 2*nRows - 2){
res.append(s.charAt(i));
}
//处理中间行
int k = 1;
for(int i = 1; i < nRows - 1; i++){
for(int j = i; j < len ; j += 2*nRows - 2){
res.append(s.charAt(j));
//判断字符访问是否越界
if((j + 2*nRows - 2 - 2*k) < len){
res.append(s.charAt(j + 2*nRows - 2 - 2*k));
}
}
k++;
}
//单独处理最后一行
for(int i = nRows - 1; i < len; i += 2*nRows - 2){
res.append(s.charAt(i));
}
return res.toString();
}
}
public class Solution {
public String convert(String s, int n) {
if(s==null || s.length()==0 || n==1)
return s;
//StringBuilder必须初始化,否则报空指针异常
StringBuilder[] sb=new StringBuilder[n];
for(int m=0;m<sb.length;m++)
sb[m]=new StringBuilder();
StringBuilder res=new StringBuilder();
boolean flag=true;
for(int i=0,j=0;i<s.length();i++)
{
sb[j].append(s.charAt(i));
if(j==n-1 && flag)
flag=false;
if(j==0 && !flag)
flag=true;
j=flag?j+1:j-1;
}
for(StringBuilder sbb :sb)
res.append(sbb.toString());
return res.toString();
}
}
/**
* 给出字符串s以及行数nRows,
* 把字符串s摆放成之字型的字符串,且一共占据nRows行
* 如,给出字符串s = 0123456789ABCDEF,
* 当nRows = 2时,
* 0 2 4 6 8 A C E
* 1 3 5 7 9 B D F
*
* 当nRows = 3时,
* 0 4 8 C
* 1 3 5 7 9 B D F
* 2 6 A E
*
* 当nRows = 4时,
* 0 6 C
* 1 5 7 B D
* 2 4 8 A E
* 3 9 F
*
* 思路:模拟生成过程
* 通过循环模拟“之”字走过的路径,
* 使用nRows个StringBuilder计算、保存最终每行的结果,
* 记迭代变量为i,遍历s,
* 当由上往下时,每个StringBuilder依次加入一个字符s[i++];
* 当由下往上时,除头尾两个StringBuilder外,依次加入一个字符s[i++],
* 直到i = s.length()。
* 最后合并每个StringBuilder。
**/
public class Solution {
public String convert(String s, int nRows) {
if (s == null || s.length() < 1 || nRows < 2) {
return s;
}
StringBuilder[] sb = new StringBuilder[nRows];
for (int i = 0; i < nRows; i++) {
sb[i] = new StringBuilder();
}
int i = 0;
while (i < s.length()) {
for (int j = 0; j < nRows && i < s.length(); j++) {
sb[j].append(s.charAt(i++));
}
for (int j = nRows - 2; j > 0 && i < s.length(); j--) {
sb[j].append(s.charAt(i++));
}
}
for (int k = 1; k < nRows; k++) {
sb[0].append(sb[k]);
}
return sb[0].toString();
}
}
class Solution {
public:
string convert(string s, int nRows)
{
if(nRows<=1)
return s;
vector<string> zigzag(nRows,"");
int step = 1,i=0,row = 0;
for(int i=0;i<s.length();i++)
{
zigzag[row] += s[i];
if(row == nRows-1) /// 确定开始向上还是向下
step = -1;
else if(row==0)
step = 1;
row += step;
}
string res = "";
for(string temp : zigzag)
res += temp;
return res;
}
};
const int maxn=927;
class Solution {
char G[maxn][maxn];
public:
string convert(string s, int nRows) {
int len=s.length();
if(!len) return "";
if(nRows==1) return s;
int i,j,index,flag=0,k;
for(i=0;i<maxn;i++)
for(j=0;j<maxn;j++) G[i][j]='#';
for(i=0,j=0,index=0;index<len;index++){
G[i][j]=s[index];
if(flag==0){
i++;
if(i+1==nRows) flag=1;
}else{
i--,j++;
if(i==0) flag=0;
}
}
string res="";
for(i=0;i<nRows;i++)
for(j=maxn-1;j>=0;j--)
if(G[i][j]=='#') G[i][j]='$';
else break;
for(i=0;i<nRows;i++){
for(j=0;j<maxn;j++)
if(G[i][j]=='#') res+="";
else if(G[i][j]=='$') //i+1!=nRows?res+="\n":res=res;
break;
else res+=G[i][j];
}
return res;
}
};
class Solution {
public:
string convert(string s, int nRows) {
if(nRows <= 1)
return s;
vector<string> z(nRows,"");
int step = 1,row = 0;
int l = s.length();
for(int i=0;i<l;i++)
{
z[row] += s[i];
if(row == 0)
step = 1;
else if(row == nRows-1)
step = -1;
row += step;
}
string result = "";
for(int i=0;i<nRows;i++)
result += z[i];
return result;
}
};
public static String convert(String s, int nRows) {
if (nRows <= 1) return s;
char[] str = new char[s.length()]; //用字符数组存储结果,StringBuilder也会爆内存。
int k = 0, i = 0, j = 0;
for (j = 0; j < nRows; j++) { //j为行序
//找到字符顺序规则,对于每行(第一列为行序)然后以2(rows-1)的大小递增,对于中间行还要加一次单个的字符位置为 当前位置i+2(nRows-j-1)
for (i = j; i < s.length(); i = i + 2 * (nRows - 1)) {
str[k++] = s.charAt(i);
int len2 = i + 2 * (nRows - j - 1);
if (j != 0 && j != (nRows - 1) && len2 < s.length())
str[k++] = s.charAt(len2);
}
}
return String.valueOf(str);
} class Solution {
public:
string convert(string s, int nRows) {
if(nRows<=1) return s;//注意特判==1的情况,因为这时2*nRows-2不会增长了
string ans;
int sz=s.size();
for(int i=0;i<nRows;i++){
if(i==0||i==nRows-1){
int k=i;
while(k<sz) ans+=s[k],k+=2*nRows-2;
}else{
int l=i,r=2*nRows-2-i;
while(l<sz||r<sz){
if(l<sz) ans+=s[l],l+=2*nRows-2;
if(r<sz) ans+=s[r],r+=2*nRows-2;
}
}
}
return ans;
}
}; public String convert(String s, int numRows) {
if (s == null || s.length() < numRows)
return s;
StringBuffer[] sb = new StringBuffer[numRows];
for (int i = 0; i < numRows; i++) {
sb[i] = new StringBuffer();
}
char[] c = s.toCharArray();
int len = s.length();
int index = 0;
while (index < len) {
for (int i = 0; i < numRows && index < len; i++) {
sb[i].append(c[index++]);
}
for(int i=numRows-2;i>0&& index < len;i--){
sb[i].append(c[index++]);
}
}
for(int i=1;i<numRows;i++){
sb[0].append(sb[i]);
}
return sb[0].toString();
}
public String convert (String s, int nRows) {
int index=0;
StringBuilder[] sb=new StringBuilder[nRows];
for(int i=0;i<nRows;i++) {
sb[i]=new StringBuilder();
}
for(int i=0;i<nRows;i++) {
sb[i]=new StringBuilder();
}
int x=0;
while(index<s.length()) {
while(x<nRows&&index<s.length()) {
sb[x++].append(s.charAt(index++));
}
x=nRows-2;
while(x>0&&index<s.length()) {
sb[x--].append(s.charAt(index++));
}
x=0;
/*
while(x>=0&&index<s.length()) {
sb[x--].append(s.charAt(index++));
}
x=1;
*/
}
for(int i=1;i<nRows;i++) {
sb[0].append(sb[i]);
}
return sb[0].toString();
} import java.util.*;
public class Solution {
/**
*
* @param s string字符串
* @param nRows int整型
* @return string字符串
*/
public String convert (String s, int nRows) {
// write code here
if (s == null || s.length() <= 2) return s;
StringBuilder sb = new StringBuilder();
int k = (nRows - 1) << 1;
int i = 0;
while(i < s.length()) {
sb.append(s.charAt(i));
i += k;
}
for(int row = 1; row < nRows - 1; ++row) {
i = row;
int kk = k - (row << 1);
while(i < s.length()) {
sb.append(s.charAt(i));
if (i + kk >= s.length())
break;
sb.append(s.charAt(i+kk));
i += k;
}
}
i = nRows - 1;
while(i < s.length()) {
sb.append(s.charAt(i));
i += k;
}
return sb.toString();
}
} import java.util.*;
public class Solution {
/**
*
* @param s string字符串
* @param nRows int整型
* @return string字符串
*/
public String convert (String s, int nRows) {
// write code here
if(nRows<=1 || s.length()<=1 || nRows>=s.length())
return s;
int flag = -1;
int num = s.length();
StringBuffer[] row = new StringBuffer[nRows];
//一定要new
for(int k=0;k<nRows;k++)
{
row[k]=new StringBuffer();
}
int i=0;
while(i<num)
{
if(flag==-1) //从上往下走
{
for(int j=0;j<nRows-1;j++)
{
row[j].append(s.charAt(i));
i++;
if(i==num)
break;
}
flag= (-1)*flag;
}
else //从下往上走
{
for(int j=nRows-1;j>=1;j--)
{
row[j].append(s.charAt(i));
i++;
if(i==num)
break;
}
flag=(-1)*flag;
}
}
for(int k=1;k<nRows;k++)
{
row[0].append(row[k]);
}
return row[0].toString();
}
} import java.util.*;
public class Solution {
/**
*
* @param s string字符串
* @param nRows int整型
* @return string字符串
*/
public String convert (String s, int nRows) {
// write code here
if(s==null || s.length()<1 ||nRows < 2) return s;
StringBuilder []str = new StringBuilder[nRows];
for(int i=0;i<nRows;i++){
str[i] = new StringBuilder();
}
int i=0;
while(i<s.length()){
for(int j=0;j<nRows && i<s.length();j++){
str[j].append(s.charAt(i++));
}
for(int j=nRows-2;j>0 && i<s.length();j--){
str[j].append(s.charAt(i++));
}
}
for(int k=1;k<nRows;k++){
str[0].append(str[k]);
}
return str[0].toString();
}
} class Solution: def convert(self , s , nRows): if s==""&nbs***bsp;nRows==1: return s pos = dict() i, index, length = 0, 1, len(s) pos[0] = s[0] while index < length: # 先往下走 k = 0 while k < nRows-1 and index < length: i = i + 1 pos[i] = pos.get(i, "") + s[index] index = index + 1 k = k + 1 # 斜着往上走 k = 0 while k < nRows-1 and index < length: i = i - 1 pos[i] = pos.get(i, "") + s[index] index = index + 1 k = k + 1 ans = "" for key, value in pos.items(): ans += value return ans
function convert( s , nRows ) {
// write code here
var arr = new Array(nRows);
var str = '';
var index = 0;
var flag = false;
for(var i = 0; i < s.length; i++){
if(i%(nRows-1) == 0){
flag = !flag
}
if(arr[index]){
arr[index] += s[i]
}else{
arr[index] = s[i]
}
if(flag){
index++
}else{
index--
}
}
for(var k in arr){
str += arr[k];
}
return str
} import java.util.*;
public class Solution {
public String convert (String s, int nRows) {
// write code here
if(nRows==1)return s;
int[] dir = {1,-1};
List<String> list = new ArrayList();
for(int i=0;i<nRows;i++)list.add("");
int j=0,k=0;
for(int i=0;i<s.length();i++){
list.set(j,list.get(j)+s.charAt(i));
if(j+dir[k]>list.size()-1||j+dir[k]<0)k=(k+1)%2;
j+=dir[k];
}
String res="";
for(int i=0;i<nRows;i++){
res+=list.get(i);
}
return res;
}
}