题目描述:
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例 1:
输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"
示例 2:
输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:
L D R
E O E I I
E C I H N
T S G
思路1:
找到每一行的元素在原字符串中的下标位置映射规律,一行一行的获取,每一行的元素直接计算出来。
代码:
1 class Solution { 2 public: 3 string convert(string s, int nrows) 4 { 5 if(s.length() == 0) 6 return ""; 7 if(nrows <= 1) 8 return s; 9 string ret = ""; 10 int len = s.length(); 11 for(int i = 0; i < nrows; i++) 12 { 13 int cur = i;//初始化为这一行的第一个元素位置下标 14 if(i == 0 || i == nrows-1) 15 { 16 while(cur < len) 17 { 18 ret += s[cur]; 19 //以“竖线的末端元素”为中间媒介比较对象 20 cur += 2*(nrows-1);//位移(行下标与行下标之间的位移)不变性的应用 21 } 22 } 23 else 24 { 25 int flag = 0; 26 while(cur < len) 27 { 28 ret += s[cur]; 29 if(flag == 0) 30 cur += 2 * (nrows-1-i); 31 else 32 cur += 2 * i; 33 flag = 1-flag; 34 } 35 } 36 } 37 38 return ret; 39 } 40 };
思路2:
需要一个额外的辅助空间,按照题目的意思,将原字符串中的字符按照z字型写入这个辅助空间中,然后按照拼接即得出要求的字符串行数为nRows的时候 周期cycle= 2*nRows-2(一个周期有这么多个数)[0,nRows-1]向下, [nRows,cycle)向上初始化一个nRows行的vector,依次将string中的每一个元素放入,再一行一行的合并。
代码:
1 class Solution { 2 public: 3 string convert(string s, int nRows) { 4 5 if(s.length() == 0) 6 return ""; 7 if(nRows <= 1) 8 return s; 9 int cycle = nRows + nRows - 2; //求出循环周期 10 vector<string> temp(nRows,""); 11 for(int i = 0; i < s.length(); i++)//流式处理,一个一个的放 12 { 13 //i这里的含义是下标,除以周期,得到的是一个周期中以0为起始下标的下标 14 //如果i的含义为以1为起始点的第几个数,除以周期,得到的是还剩几个数(从计数意义上说) 15 int index = i%cycle; 16 if(index < nRows) 17 temp[index]+=s[i];//往下走 18 else//位移不变性 19 temp[(nRows-1)-(index-(nRows-1))]+=s[i];//往上走 20 } 21 22 string ret=""; 23 for(int i = 0; i < nRows; i++) 24 ret += temp[i]; //合并 25 return ret; 26 } 27 };
和上面的思路一样,但使用了不同的实现:
1 class Solution { 2 public: 3 string convert(string s, int nRows) 4 { 5 6 if(s.length() == 0) 7 return ""; 8 if(nRows <= 1) 9 return s; 10 vector<string> temp(nRows,""); 11 int len=s.length(); 12 int i=0; 13 while(i<len)//这里外面的循环是如果还有元素时就一个周期一个周期的添加 14 { //(上面的实现是一个元素一个元素的添加) 15 for(int j=0;j<nRows && i<len;j++) 16 temp[j]+=s[i++]; 17 for(int j=nRows-2;j>0 && i<len;j--) 18 temp[j]+=s[i++]; 19 } 20 string ret=""; 21 for(int i=0;i < nRows;i++) 22 ret+=temp[i]; 23 return ret; 24 } 25 };