題目區(qū)(源自于leetcode)
將一個給定字符串根據(jù)給定的行數(shù)走敌,以從上往下惯豆、從左到右進(jìn)行 Z 字形排列。
比如輸入字符串為 "LEETCODEISHIRING" 行數(shù)為 3 時跪解,排列如下:
L C I R
E T O E S I I G
E D H N
之后炉旷,你的輸出需要從左往右逐行讀取,產(chǎn)生出一個新的字符串叉讥,比如:"LCIRETOESIIGEDHN"窘行。
請你實現(xiàn)這個將字符串進(jìn)行指定行數(shù)變換的函數(shù):
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
思路說明
通過題目解釋可以看出規(guī)律:輸入的字符串以從上到下開始排列,到最后一行后沿著對角線逐漸回到第一行(不包括第一行)图仓,循環(huán)往復(fù)罐盔。那么每一行取得數(shù)組的下標(biāo)就有了規(guī)律,是一個帶有周期性圖形重復(fù)救崔。那么就可以歸納如下(假設(shè)有n行):
從圖形我們可以看出周期為pace = n*2-2
第一行
從下標(biāo)0開始惶看,每個周期只會取到一個字符,每次增加一個周期(n*2-2)
第二行到第n-1行
在每一個周期內(nèi)只會取到最多兩個字符六孵。第一個字符從下標(biāo)(當(dāng)前行數(shù)j-1)開始纬黎,每次增加一個周期(n*2-2);第二個字符從下標(biāo)(n*2-2-當(dāng)前行數(shù)j+1)開始劫窒,每次增加一個周期(n*2-2)
第n行
從下標(biāo)n-1開始本今,每次增加一個周期(n*2-2)
源碼區(qū)
#include <string.h>
#include <stdio.h>
char * convert(char * s, int numRows);
main() {
char input[50] = {"LEETCODEISHIRING"};
int num = 4 ;
char * s = convert(input,num);
printf("%s",s);
}
char * convert(char * s, int numRows) {
if(numRows==1) {
return s;
}
int size = strlen(s);//數(shù)組的長度
char result[size];
memcpy(result,s,sizeof(char)*size);
int pace = 2*numRows-2;//一個周期數(shù)據(jù)長度
int j=0;
while(j<size) { //處理第一行
*(s++)= result[j];
j+=pace;
}
j = 1;//將行數(shù)指向第二行
for(; j<numRows-1; j++) { //默認(rèn)除了第一行和第n-1行都有兩個數(shù)字
int k1 = j;
int k2 = pace-k1;
while(1) {
if(k1>size-1) { //判斷第一個數(shù)是否存在,不存在跳出
break;
}
*(s++) = result[k1];
if(k2>size-1) { //判斷第二個數(shù)是否存在,不存在跳出
break;
}
*(s++) = result[k2];
k1+=pace;
k2+=pace;//向后移動一個周期
}
}
while(j<size) { //處理最后一行
*(s++) = result[j] ;
j+=pace;
}
return s-size;
}