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》
以上面这个例子解释:
遍历原始字符串,用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
135791113
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 57 1113
24 810  
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<len(s)-interval:
                ans +=(s[j]+s[j+innergap])    #while循环里先把1、3、5、7放进去
                j += interval
            if j < len(s):        #然后判断9是否越界
                ans += s[j]
            if j+innergap < len(s):    #再判断11是否越界
                ans += s[j+innergap]

 

    原文作者:Z字形编排问题
    原文地址: https://blog.csdn.net/xinxin100011/article/details/81258144
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞