[leetcode] 6. ZigZag Conversion

556 篇文章 2 订阅
441 篇文章 0 订阅

Description

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

分析

题目的意思是:把字符串转换成之字形的然后输出。

比如有一个字符串 “0123456789ABCDEF”,转为zigzag
当 n = 2 时:

0 2 4 6 8 A C E

1 3 5 7 9 B D F

当 n = 3 时:


0   4   8   C

1 3 5 7 9 B D F

2   6   A   E

当 n = 4 时:

0      6      C
1    5 7    B D
2  4   8  A   E
3      9      F

除了第一行和最后一行没有中间形成之字型的数字外,其他都有,而首位两行中相邻两个元素的index之差跟行数是相关的,为 2*nRows - 2,

  • 根据这个特点,我们可以按顺序找到所有的黑色元素(例如n=4中的第一列)在元字符串的位置,将他们按顺序加到新字符串里面
  • 对于红色元素出现的位置也是有规律的,每个红色元素(例如n=4中的第二列)的位置为 j + 2nRows-2 - 2i, 其中,j为前一个黑色元素的列数,i为当前行数。
  • 比如当n = 4中的那个红色5,它的位置为 1 + 24-2 - 21 = 5,为原字符串的正确位置。
  • 当我们知道所有黑色元素和红色元素位置的正确算法,我们就可以一次性的把它们按顺序都加到新的字符串里面。

C++代码

class Solution {
public:
    string convert(string s, int numRows) {
        if(numRows<=1){
            return s;
        }
        string res="";
        int len=2*numRows-2;
        for(int i=0;i<numRows;i++){
            for(int j=i;j<s.size();j+=len){
                res+=s[j];
                int temp=j+len-2*i;
                if(i!=0&&i!=numRows-1&&temp<s.size()){
                    res+=s[temp];
                }
            }
        }
        return res;
    }
};

Python 代码

这道题主要是找规律,找出N的周期,然后根据这个周期和当前所处的行来确定每一个字符的位置。

class Solution:
    def convert(self, s: str, numRows: int) -> str:
        n = len(s)
        if numRows==1:
            return s
        res = ''
        t = 2*numRows-2
        # P 0  A 4 H 8 N 12
        # A 1 P 3 L 5 S 7 I 9 I 11
        # Y 2 I 6 R 10
        for row_num in range(numRows):
            for i in range(0,n-row_num,t):
                res+=s[i+row_num]
                j = i+t-row_num
                if 0<row_num<numRows-1 and j<n:
                    res+=s[j]
        return res

上面的规律不容易想到出来,下面的解法是直接模拟:

class Solution:
    def convert(self, s: str, numRows: int) -> str:
        # P 0  A 4 H 8 N 12
        # A 1 P 3 L 5 S 7 I 9 I 11
        # Y 2 I 6 R 10
        if numRows==1:
            return s
        rows = ['']*numRows
        cur_row = 0
        direction = 1

        for ch in s:
            rows[cur_row]+=ch
            cur_row+=direction
            if cur_row==0 or cur_row==numRows-1:
                direction*=-1

        return "".join(rows)

参考文献

[编程题]zigzag-conversion
[LeetCode] ZigZag Converesion 之字型转换字符串

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

农民小飞侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值