力扣刷题笔记 Z字形变换

前言

本文是为了记录自己做题的思路,便于之后优化。

正文

看到题目的第一感觉是找规律:

s = "PAYPALISHIRING"
numRows = 4
print(len(s))
#6n
print(s[0],s[6],s[12])
#6n-1 6n+1
print(s[1],s[5],s[7],s[11],s[13])
#6n+2 6n-2
print(s[2],s[4],s[8],s[10])
# 6n+3
print(s[3],s[9])

输出结果为:

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

结果与答案是一致的,所以这里利用这种找规律的方法进行获取,把这个总结成一个循环,但是在总结循环的时候发现,不是所有的都是这个规律,如果行数不是4的话,这个规律就不再适用了,同时对于这里面的元素,进行一一的异常排除也不现实,所以更改思路:
根据所给出的行数与原本的数字的索引来找规律,我们不难发现,纵向的数据个数为n个,斜着的个数为n-2个,所以每组对应的数目应当为2n-2个,这样看来,我们需要首先找到其终止位置对应的这里面的序列应当是第几个,也就是其下标截止于几,最简单的思考方法是利用一个新的数组存放这些数据,但是实际上这样做会浪费大量的内存,因此必须要用下标来表示,这里按照迭代的次数i来表示,最终结束是在某个特定的位置结束,迭代后每次变化的数字的个数为0,1,2,3…2n-3,也就是看何时达到一个最终的数值,这一簇结束位置为何处,修改代码后,如下:

s = "PAYPALISHIRING"
numRows = 4
T=2*numRows-2
string=list()

while True:
    n=0
    while True:
        if T*n>=len(s):
            break
        else:
            string.append(s[T*n])
            n+=1
            print(string)
    
    for i in range(1,numRows-1):
        n=0
        while True:
            if T*n+i<len(s):
                string.append(s[T*n+i])
                print(string)
            else:
                break
            if T*(n+1)-i<len(s):
                string.append(s[T*(n+1)-i])
                print(string)
            else:
                break
            n+=1
    n=0
    while True:
        if T*n+numRows-1>=len(s):
            break
        else:
            string.append(s[T*n+numRows-1])
            print(string)
            n+=1
    print(len(string))    
    if len(string)==len(s):
        break
['P']
['P', 'I']
['P', 'I', 'N']
['P', 'I', 'N', 'A']
['P', 'I', 'N', 'A', 'L']
['P', 'I', 'N', 'A', 'L', 'S']
['P', 'I', 'N', 'A', 'L', 'S', 'I']
['P', 'I', 'N', 'A', 'L', 'S', 'I', 'G']
['P', 'I', 'N', 'A', 'L', 'S', 'I', 'G', 'Y']
['P', 'I', 'N', 'A', 'L', 'S', 'I', 'G', 'Y', 'A']
['P', 'I', 'N', 'A', 'L', 'S', 'I', 'G', 'Y', 'A', 'H']
['P', 'I', 'N', 'A', 'L', 'S', 'I', 'G', 'Y', 'A', 'H', 'R']
['P', 'I', 'N', 'A', 'L', 'S', 'I', 'G', 'Y', 'A', 'H', 'R', 'P']
['P', 'I', 'N', 'A', 'L', 'S', 'I', 'G', 'Y', 'A', 'H', 'R', 'P', 'I']
14                   

转移到leetcode中去,出现了几个超时的,发现都是numRows=1的,所以修改代码如下:

class Solution:
    def convert(self, s: str, numRows: int) -> str:        
        if numRows==1:
            return s
        T=2*numRows-2
        string=list()
        while True:
            n=0
            while True:
                if T*n>=len(s):
                    break
                else:
                    string.append(s[T*n])
                    n+=1
            
            for i in range(1,numRows-1):
                n=0
                while True:
                    if T*n+i<len(s):
                        string.append(s[T*n+i])
                    else:
                        break
                    if T*(n+1)-i<len(s):
                        string.append(s[T*(n+1)-i])
                    else:
                        break
                    n+=1
            n=0
            while True:
                if T*n+numRows-1>=len(s):
                    break
                else:
                    string.append(s[T*n+numRows-1])
                    n+=1  
            if len(string)==len(s):
                break

        return ''.join(string)            

力扣刷题笔记 Z字形变换_第1张图片
时间上有待提高,空间上还可以,有时间再优化吧。

你可能感兴趣的:(leetcode,算法,职场和发展)