LeetCode (6)ZigZag Conversion

31 篇文章 0 订阅

(6)ZigZag Conversion

题目:字符串“PAYPALISHRING”写的是一个给定的字符串,写成这样一个曲折模式:

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

然后逐行读取:“PAHNAPLSIIGYIR”。

编写代码,会提供需要的字符串和变换成的行数:

string convert(string text, int nRows);

convert(“PAYPALISHIRING”,3)需要返回”PAHNAPLSIIGYIR”。

看到这道题就想到了原来学习C语言做的输出图形之类的题目,感觉很简单,唯一的问题就在于如何推导关系公式,在纸面上自己画了一下,看了一看就获取了每个位置的关系公式。

首先定义一个单位,将整个转换后的ZigZag图形分成一个一个小的单位,就比如我将左侧开始从第一列到第n-1列分为一个小单元,这样每个小单元组成一个整个的图形。

每个单元中的数字分别为:

1               (2n-1)(这个位置其实是下一个单元的第一个数字)
2             2n-2
3             ·
·           ·
·         · 
·       n+2
n-1   n+1
n      

这样我们可以发现,每个数字的关系其实就是如上图所示,我们发现第一列的数字其实就是行数,行数的上限就是题目的numRows,但是可能有人觉得在这个图中第二列往后的每列数字不好和行数关系起来,那么不妨我们分析一下,(n-1) + (n+1) = 2n, 2+(2n - 2) = 2n,那我们可以转换成下图

1                    2n-1
2                 2n-(2)
3                 ·
·               ·
·             ·
·        2n-(n-2)
n-1   2n-(n-1)
n 

这样我们就找到了解题的方式了,除了第一行和最后一行, 每一行的分别是行数i以及(2n-i)这两个字符,然后每一个小单位里面一共有2n-2个单位字符,那么下一个单位就是每个字符加上2n-2,每次判断是否超过长度就可以了。

另外我们需要考虑一个问题就是2n-2有可能为零,此时n=1,我们需要添加一条就是n=1的时候直接返回原字符串就可以了,因为以1做ZigZag就是本身。

代码如下:

class Solution {
public:
    string convert(string s, int numRows) {
        int i = 1, j = 0;
        int len = s.size();
        string str = "";
        if( numRows == 1){
            return s;
        }
        for(i = 1; i <= numRows; i ++){
            if(i == 1|| i == numRows){
                j = i;
                while(j <= len){
                    str += s.substr(j-1, 1);
                    j += (2*numRows - 2);
                }
            }
            else{
                j = i;
                int k = ((2*numRows)-j);
                while(j <= len){
                    str += s.substr(j-1, 1);
                        if(k <= len){
                            str += s.substr(k-1, 1);
                        }
                    j += (2*numRows - 2);
                    k += (2*numRows - 2);
                }
            }
        }
        return str;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值