Leetcode6. Z字形变换——模拟法

6. Z 字形变换

Difficulty: 中等

将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:

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

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

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);

示例 1:

输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"

示例 2:

输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:

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

纯模拟,不愿找规律🤣 二维数组的方法大部分人都能想到,就看怎么优化了。

题目分析:

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

可以简化为

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

(所以说Z字排列和N字排列差不多就是一回事

numRows*2-2个数为一组,分两列往新列表里装(第二列别忘了有空白),新列表中每隔numRows个数就是同一行,就这样遍历新列表,得到所求字符串。

遇到的问题:

  1. 怎么按numRows个,numRows-2个,numRows个,numRows-2个…来分割字符串。(于是写出来很蠢)
  2. join跟split忘了咋用了
    join:'分隔符'.join(含字符串列表)
    split:字符串.split('分隔符')
  3. 切片object[start_index:end_index:step]:当step为负时,起点值应该比终点值大(一开始忘了,切出来是空的…太菜了)。 看这个复习一下

扁平二维数组的结构:
在这里插入图片描述

class Solution(object):
    def convert(self, s, numRows):
        """
        :type s: str
        :type numRows: int
        :rtype: str
        """
        if numRows<2:
            return s
        l=[]
        s=list(s)
        #产生新列表(实际上是扁平化的二维数组)
        while len(s)>=numRows*2-2:
            l+=s[:numRows]
            s=s[numRows:]
            l+=['0']+s[:numRows-2][::-1]+['0']
            s=s[numRows-2:]
        if len(s)<=numRows:
            l+=s
        else:
            l+=s[:numRows]
            s=s[numRows:]
            l+=['0']*(numRows-2-len(s)+1)+s[::-1]#前边用0补全
        #读取新列表
        L=[]
        for k in range(numRows):
            L+=l[k::numRows]#一行
        return ''.join(''.join(L).split('0'))

赞美这篇大佬写的模拟,利用flag控制每个元素加入哪一行,很巧妙。⬇代码

class Solution:
    def convert(self, s: str, numRows: int) -> str:
        if numRows < 2: return s
        res = ["" for _ in range(numRows)]
        i, flag = 0, -1
        for c in s:
            res[i] += c
            if i == 0 or i == numRows - 1: flag = -flag
            i += flag
        return "".join(res)
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值