LeetCode Notes_#6 Zigzag Conversion

LeetCode Notes_#6 Zigzag Conversion

Contents

题目

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

不要看这个例子,看不懂的,看下面的图

思路和解答

思路

这其实是一个找规律的题,看了半天才看懂题目所说的zigzag扫描是怎么回事,如下图....

zigzag转换
zigzag转换

要找到z字型书写的每一个字符在原来的字符串里边的索引

  • 黑色字
    • 每一行第一个黑色字符的在原字符串的索引就是行号
    • 每一行两个相邻的黑色字符,在原字符串里边的索引相差6(2*n-2)
  • 红色字
    • 红色字符在原字符串里的位置j + 2* nRows-2 - 2* i, 其中,j为前一个黑色元素的列数,i为当前行数。 比如当n = 4中的那个红色5,它的位置为 1 + 2* 4-2 - 2* 1 = 5,为原字符串的正确位置。
  • 根据以上两点规律就可以写代码了
    • 还是用到两层循环,两个指针,行指针i,列指针j;根据行列,计算出每个字符在原字符串里的位置,然后一个字符一个字符的拼接起来

解答

# 照着java解答写的...的确没啥思路
class Solution(object):
    def convert(self, s, numRows):
        """
        :type s: str
        :type numRows: int
        :rtype: str
        """
        if (numRows <= 1):
            return s
        res=''
        step=2*numRows-2
        for i in range(numRows):
            for j in range(i,len(s),step):
                res=res+s[j]
                tmp=j+step-2*i
                if (i!=0 and i!=numRows-1 and tmp<len(s)):
                    res=res+s[tmp]
        return res

72ms,beat 60%

要注意的一些点

  • 看懂所谓z字型的转换方式,感觉是字体原因所以看起来不好理解,其实这种情况没必要用文本,直接画一个图更好
  • 看懂意思,抽象出规律的表达式,代码其实不太难

参考

posted @ 2018-10-26 11:58  Howfar's  阅读(236)  评论(0编辑  收藏  举报