Z字形变换

题目:将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:

L   C   I   R
E T O E S I I G
E   D   H   N

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"

来源:https://leetcode-cn.com/problems/zigzag-conversion/

法一:自己的代码

思路:通过枚举输入字符串构成Z后的索引,找到索引的规律,首末行和其余行都是由数列构成,且公差一致,区别是首末行是单个的数列,而其余行是两个公差一致的交错数列构成,故问题便转化成了将若干个数列取前几项放入一个list中,由于输出的要求,必须是从第一行到最后一行逐一进行append,且append前要先判断数列索引是否超出的字符串的长度,得到str_index后,即可直接由索引找到对应的元素并输出

 

思路:通过枚举输入字符串构成Z后的索引,找到索引的规律,首末行和其余行都是由数列构成,
且公差一致,区别是首末行是单个的数列,而其余行是两个公差一致的交错数列构成,
故问题便转化成了将若干个数列取前几项放入一个list中,
但必须是从第一行到最后一行逐一进行append,且append前要先判断数列索引是否超出的字符串的长度,
得到str_index后,即可直接由索引找到对应的元素并输出
class Solution:
    def convert(self, str, numRows):
        if numRows == 1:  # 1比较特殊 单独进行判断
            print(str)
        else:
            str_index = []
            for i in range(numRows):
                j = 0     # j用于记录Z中第一行和最后一行的公差倍数
                k = 0     # 当不是首末行时,会有两个首项不同的数列,k用于记录Z中非首末行的公差倍数
                tolerance = 2 * (numRows - 1)
                print(tolerance)
                if i == 0:
                    while (j * tolerance) < len(str) and j < len(str):
                        # str_index[j * tolerance] = j * tolerance
                        str_index.append(j * tolerance)
                        j = j + 1
                    print(str_index)
                elif i == (numRows-1):
                    while ((numRows-1) + j * tolerance) < len(str):
                        str_index.append((numRows-1) + j * tolerance)
                        j = j + 1
                    print('kkkkkkkk')
                    print(str_index)
                else:
                    # tolerance_1 = tolerance - 1 - i * 2
                    # tolerance_2 = tolerance - 1 - (numRows - i) * 2
                    while (i + j * tolerance) < len(str):
                        # print(i + j * tolerance)
                        # print('公差是', tolerance)
                        # print('i is:', i)
                        # print('j is:', j)
                        str_index.append(i + j * tolerance)
                        j = j + 1
                        # 交错判断两个数列是否超出了len(str),由于两个数列是交错穿插的,所以第二个数列判断完后直接break
                        while (tolerance - i + k * tolerance) < len(str):
                            # tolerance - i * 2 是第二个数列的首项
                            str_index.append(tolerance - i + k * tolerance)
                            k = k + 1
                            break
                    print(str_index)
            print(str_index)
            final_str = []
            for i in range(len(str)):
                final_str.append(str[str_index[i]])
            print("".join(final_str))

if __name__ == '__main__':
    duixiang = Solution()
    s = "AB"
    print(len(s))
    duixiang.convert( s, 1 )

    # "PAYPALISHIRING"
    # 4
View Code

 

法二:

思路:仍然是找到数列的规律后,逐行进行判断,问题的关键仍然是如何确定首项及公差,特别是除首末行外其余行的第二个数列,其中第一个数列的最大值是由for i in range(j, l, count):所限定的,第二个数列的最大值由if temp < l 限定的。要学会for i in range(j, l, count)的写法

 

思路:仍然是找到数列的规律后,逐行进行判断,问题的关键仍然是如何确定首项及公差,特别是除首末行外其余行的第二个数列,
其中第一个数列的最大值是由for i in range(j, l, count):所限定的,第二个数列的最大值由if temp < l 限定的。
要学会for i in range(j, l, count)的写法
class Solution:
    def convert(self, s: str, numRows: int) -> str:
        if numRows == 1:
            return s
        count = 2 * numRows - 2
        print(count)
        re_str = ''
        l = len(s)
        j = 0
        while j < numRows:
            for i in range(j, l, count):   # count是数列的公差
                print('i is:', i)
                re_str += s[i]
                temp = i + count - 2 * j
                print('temp is:', temp)
                if temp < l and (temp % count) != 0 and temp != i:
                    re_str += s[temp]
                    print('re_str is:',re_str)
            j += 1
        return re_str


if __name__ == '__main__':
    duixiang = Solution()
    s = "LEETCODEISraefasfafasfasfdasfHIRING"
    print(duixiang.convert(s, 4))
View Code

 

posted on 2019-07-11 22:24  吃我一枪  阅读(623)  评论(0编辑  收藏  举报

导航