1.题目


The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)

P   A   H   N
A P L S I I G
Y I R

And then read line by line: "PAHNAPLSIIGYIR"

Write the code that will take a string and make this conversion given a number of rows:

string convert(string s, int numRows);

Example 1:

Input: s = "PAYPALISHIRING", numRows = 3
Output: "PAHNAPLSIIGYIR"

Example 2:

Input: s = "PAYPALISHIRING", numRows = 4
Output: "PINALSIGYAHRPI"
Explanation: P I N
A L S I G
Y A H R
P I

题目大意是要求将一个给定字符串转换为之字形字符串,示意图如下:

2.思路


读完题后第一想法是,找出一种映射关系使得原字符串的下标能够映射为之字形的二维坐标,以题目中给的字符串"PAYPALISHIRING"为例,假定numRows为4,则该二维数组最多4行(若字符串长度小于numRows则不足4行,只有strlen(s)行),但如果这么做,将会浪费大量的空间,而且最终要求返回的字符串长度与输入字符串的长度是相等的,应该存在更简单的做法.

仔细观察变换后的之字形字符串,对于水平方向第一行和最后一行的元素来说,实际上就是原字符串中间距为STEP的元素,其中STEP=2*(numRows-1).还是以"PAYPALISHIRING"为例,设numRows为4,则第一行的元素是:

S[0]='P',S[6]='I',S[12]='N';

最后一行的元素是:

S[3]='P',S[9]='I';

但对于中间的行来说,两个元素间的间距是变化的,所幸这种变化也有规律可循,那就是两次连续的间距之和等于STEP,这样如果我们知道起始两个元素的间距,后面所有元素的间距都能计算出来.从示意图中容易发现,行号越小则起始两元素的间距越大,可以猜测间距应该是一个跟行号相关的变量,实际上行号每加1,间距就减少2,间距减少到0的时候则回绕为STEP.(设第一行起始两个元素的下标为begin,end,对于本例来说begin=0,end=6,那么第二行的起始两个元素的下标就是begin = begin + 1, end = end - 1,显然间距减少了2).有了这些条件,我们就能将原字符串映射为之字形的字符串,具体做法如下:

  1. 从下标0开始,取出所有间距为STEP的元素;
  2. 从下标1开始,取出间距为N的元素,N是一个变化的值,初始值为4,接着变为2,接着又变为4
  3. ......
  4. 从下标i开始,取出间距N=STEP-2*i的元素,接着取出间距为N=STEP-N的元素,两次连续的间距之和为STEP
  5. 若i等于numRows则循环终止

3.实现


char* convert(char* s, int numRows) {
size_t len, i, j, k, m, step;
char *ret; if (numRows == )
return s; len = strlen(s);
ret = malloc((len + ) * sizeof(char)); k = ; /* 转换后的字符串下标 */
m = * (numRows - );
for (i = ; i < numRows; ++i) {
step = m - * i > ? m - * i : m;
for (j = i; j < len; ) {
ret[k++] = s[j];
j += step;
step = m - step > ? m - step : m;
}
}
ret[len] = ;
return ret;
}

虽然整个算法是两层for循环,但时间复杂度并不是O(n2)而是O(n),因为整个算法保证对原字符串每个字符只处理一次,比较直观的解释是内层循环的步长是跳跃式的.

ZigZag Conversion 之字形转换字符串的更多相关文章

  1. 【LeetCode】6. ZigZag Conversion Z 字形变换

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 公众号:负雪明烛 本文关键词:字形变换,ZigZag,题解,Leetcode, 力扣,P ...

  2. 【LeetCode】ZigZag Conversion(Z 字形变换)

    这道题是LeetCode里的第6道题. 题目要求: 将一个给定字符串根据给定的行数,以从上往下.从左到右进行 Z 字形排列. 比如输入字符串为 "LEETCODEISHIRING" ...

  3. 【LeetCode】6. ZigZag Conversion 锯齿形转换

    题目: 思路: 以图为例:s={'A','B','C','D','E','F','G','H'.....} 1.先不考虑中间元素F.G.H.N...,每一行前后元素在数组中对应下标相差size=2*n ...

  4. 字符串按照Z旋转90度然后上下翻转的字形按行输出字符串--ZigZag Conversion

    The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like ...

  5. Leetcode 6 ZigZag Conversion 字符串处理

    题意:将字符串排成Z字形. PAHNAPLSIIGYIR 如果是5的话,是这样排的 P     I AP   YR H L G N  SI A    I 于是,少年少女们,自己去找规律吧 提示:每个Z ...

  6. LeetCode 6. ZigZag Conversion & 字符串

    ZigZag Conversion 看了三遍题目才懂,都有点怀疑自己是不是够聪明... 就是排成这个样子啦,然后从左往右逐行读取返回. 这题看起来很简单,做起来,应该也很简单. 通过位置计算行数: P ...

  7. LeetCode ZigZag Conversion(将字符串排成z字型)

    class Solution { public: string convert(string s, int nRows) { string a=""; int len=s.leng ...

  8. No.006 ZigZag Conversion

    6. ZigZag Conversion Total Accepted: 98584 Total Submissions: 398018 Difficulty: Easy The string &qu ...

  9. LeetCode--No.006 ZigZag Conversion

    6. ZigZag Conversion Total Accepted: 98584 Total Submissions: 398018 Difficulty: Easy The string &qu ...

随机推荐

  1. html 出现粒子线条,鼠标移动会以鼠标为中心吸附的特效之canvas-nest.js插件

    我在网上看到一个很炫酷,很有趣的特效,网页上会有很多移动的粒子和线条,鼠标经过时会以鼠标为中心吸附过来,如果时间够久,会形成一个类似震动的.带辐条的车轮子的东西. 网上搜了一下,源码是github里面 ...

  2. idea jdk版本问题

    问题描述: Information:Using javac 1.6.0_43 to compile java sourcesInformation:java: Errors occurred whil ...

  3. 小梵同学 GO!

    刘德翠 1. Vue.js实战读书笔记(1) 2.Vue.js实战读书笔记--计算属性 3. Vue.js实战读书笔记--v-bind及class与style绑定 4. Vue.js实战读书笔记--内 ...

  4. E4A 与JS交互事件无反应

    今天碰到一个问题,E4A与JS的交互,调用JS函数后,事件没有任何反应,给JS赋值,会看到浏览框中有内容显示,但是事件为什么就没反应呢. 把官方的例程打开编译试了也不行. 后来在群中问了,原来是这里设 ...

  5. Assets Library开发总结

    Assets Library beta版的开发工作告一段落,本着有始有终的原则,这个项目还是需要做个总结的,恩~ 先甩一个链接:https://vimeo.com/238186671 考虑到该项目开发 ...

  6. C++指针速记

    基本原则:指针类型变量存储的就是地址! 1.数组名就是数组首元素的地址** int age[3]; int* p = age; 2.使用new操作符实际上是向操作系统申请一块内存(包含类型信息),返回 ...

  7. Linux常见企业面试题

    1:只查看test.txt (100行)文件中第20行到30行的数据(企业常见面试题) 答: seq (序列) 第一种方法:head -30 test1.txt | tail -11 第二种方法:se ...

  8. php对函数的引用

    function &example($tmp=0){                  //定义一个函数,别忘了加“&”符     return $tmp;              ...

  9. java 垃圾回收总结(1)(转)

    转自: http://www.cnblogs.com/aigongsi/archive/2012/04/06/2434771.html 另外可参考: http://ifeve.com/gc-orien ...

  10. centos 6.5 安装redis

    1. 下载redis,编译安装 下载地址:https://redis.io/download(建议大家都选择稳定版本) 下载到本地,然后上传到集群 当然也可以通过命令行直接在线下载 $ wget ht ...