字符串"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; } }