leetcode6 Z字形变换 python

题目:

将字符串 "PAYPALISHIRING" 以Z字形排列成给定的行数:

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

之后从左到右"PAHNAPLSIIGYIR"
实现一个将字符串进行指定行数变换的函数。

思路: 

1. 官方答案版本1

        leetcode6 Z字形变换 python_第1张图片
以上面这个例子解释:
遍历原始字符串,用currow变量记录所处的行,即让currow变换为0,1,2,1,0,1,2,1,0,1,2,1,0,1......
(如果numRows是4行currow就是0,1,2,3,2,1,0,1,2,3,2,1...... )
同时初始化一个长度为3,元素为字符串的列表rows。
每到currow行,就把遍历到的字符s加入到rows相应元素,
如第0行,rows[0]+=s,第1行,rows[1]+=s ...... 最后再把rows按顺序输出就好了。

如何让currow按需变换,需要再有个变量godown 记录方向,到0或numRows-1 行的时候,godown变向,决定currow加一或者减一。
需要注意
①原字符串长度可能小于numRows,所以列表长度为min(numRows, len(s))   
②遇到numRows = 1,直接return s。

class Solution:
    def convert(self, s, numRows):
        """
        :type s: str
        :type numRows: int
        :rtype: str
        """
        if numRows == 1:
            return s

        rows = ['']* min(numRows, len(s))
        godown = False
        currow = 0
        for c in s:
            rows[currow] += c
            if currow == 0 or currow == numRows-1:
                godown = not godown
            if godown:
                currow += 1
            else:
                currow -= 1
        return ''.join(rows)

2. 官方答案版本2

  主要是找出数字索引与行列数的关系。

0   4   8   12
1 3 5 7 9 11 13
2   6   10    

    numRows有3行,完全有数字的列,间隔interval=4,(4=2*3-2)
    第0行:0,4,8,12...... (从0开始间隔4)
    第numRows-1行:2,6,10...... (从numRows-1开始间隔4)
    第1行:1,5,9,13... 也是间隔4,然后3比1大2, 7比5大2,11比9大2... (行内间隔innergap=2)

0     6     12
1   5 7   11 13
2 4   8 10    
3     9      

    numRows=4,interval=2*4-2=6。第0行和最后一行规律同上。
    主要看innergap的规律,5---1,2---4的和都是6(interval),我们想求的是5减1,4减2,即innergap = interval - 2*i(i是行序号)
    这个方法好像比上一个慢,不知道是不是对字符串s的访问太跳跃的原因>.<

class Solution:
    def convert(self, s, numRows):
        """
        :type s: str
        :type numRows: int
        :rtype: str
        """
        if numRows == 1:
            return s
        
        ans = ''
        interval = 2*numRows -2
        
        ans += s[::interval]    #第0行,第一个例子里的0,4,8
        
        for i in range(1, numRows-1):    #第1到倒数第2行
            innergap = interval - 2*i
            for j in range(i, len(s),interval):
                ans += s[j]                #例子里的1,5,9
                if j + innergap < len(s):    #注意越界
                    ans += s[j+innergap]    #例子里的3,7
                    
        ans += s[numRows-1::interval]    #最后1行,例子里的2,6
        return ans

 发现, i、j循环里,j+innergap每次都要判断越界,稍微改进直到一行最后才判断,会变快^0^

        for i in range(1, numRows-1):    #第1---倒数第2行
            innergap = interval - 2*i
            j = i
            while j

 

你可能感兴趣的:(leetcode6 Z字形变换 python)