我为什么又开始刷题了,还发现了个秘密...

简介: 我为什么又开始刷题了,还发现了个秘密...

简说Python,号主老表,Python终身学习者,数据分析爱好者,从18年开始分享Python知识,原创文章227篇,写过Python、SQL、Excel入门文章,也写过Web开发、数据分析文章,老表还总结整理了一份2022Python学习资料和电子书资源,关注后私信回复:2022 即可领取。

一、写在前面

好久没刷题了,最近看了点啥,备受鼓舞,决定每天刷一刷,也是一个和大家沟通交流的渠道,更具体的我为什么选择又开始刷题,下回再和大家分享,不搞悬疑,我发现的秘密可以见评论区。

前期不打算建相关学习交流群,不过Python学习交流群还是一直开放的哈,那么就开始今天的刷题吧。

LeetCode 第18篇刷题笔记传输门:继续刷Leetcode,第18篇

今天给大家分享的是老表刷LeetCode  第十九篇:Z字形变换,为面试而生,期待你的加入。

Use the utility in the API is recommended in the project. But if you use it in an interview, you will definitely fail .

二、今日题目

将一个给「定字符串」根据「给定的行数」,以「从上往下、从左到右进」行 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

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/zigzag-conversion

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

三、 分析

这个题目,看着有点复杂,需要好好读和理解题目,首先确定输入、输出、其他变量、变换逻辑这三部分:

输入:字符串
输出:字符串
其他变量:给定的行数
变换逻辑:字符串以从上往下、从左到右进行遍历输出成 Z 字形排列

从变换逻辑来看,可以知道,主要是考察字符串的遍历。

四、解题

这里给大家分享两个大佬的解题方法。

1. Leetcode大佬Krahets的解法:循序遍历

时间复杂度,遍历一边数组:O(N)

空间复杂度,多用了一个res存储返回字符串:O(N)

(1)代码
class Solution(object):
    def convert(self, s, numRows):
        """
        :type s: str
        :type numRows: int
        :rtype: str
        """
        # 如果指定行数小于2,就是1,一行直接输出字符串即可
        if numRows < 2:
            return s
        # 构建一个列表存储输出结果
        # 保证列表长度和字符串长度相同即可,构建方法很多
        res = ["" for _ in s]
        # 很重要,i 为索引下标,flag 是一个标识符,这里作者应用的很智慧
        i, flag = 0, -1
        # for循环便利输入字符串
        for c in s:
            # 存储输出字符串
            # 等价于 res[i] = res[i] + c
            res[i] += c
            # 很智慧,到这一步我们会发现索引下标i的界限[0, numRows - 1]
            # [0, numRows - 1]区间跨度也就是 numRows
            # 当到达边界的时候,flag = -flag 进行转向,保证i永远在[0, numRows - 1]
            if i == 0 or i == numRows - 1:
                # 转向
                flag = -flag
            # 前进或后退
            # 等价于 i = i + flag
            i += flag
            # 循环遍历字符串,直至字符串遍历完
        # 利用join函数连接res列表里的每个元素
        # 到此解题完毕
        return "".join(res)
(2)提交结果

image.png

测试数据:1157个测试用例

运行时间:44 ms,击败92%

内存消耗: 13 MB,击败46%

好奇心驱使,我看了看执行时间top1的代码,和Krahets大佬的代码是一样的。。。image.png

我又看了看内存消耗最低的代码,我发现这就是我即将要和大家分享的第二位大佬的解题思路。

image.png

2.Leetcode大佬Zoffer的解法:周期打印

时间复杂度:O(N)

空间复杂度:O(N)

(1)代码
class Solution(object):
    def convert(self, s, numRows):
        """
        :type s: str
        :type numRows: int
        :rtype: str
        """
        # 如果指定行数小于2,就是1,一行直接输出字符串即可
        if numRows < 2:
            return s
        # 构建一个列表存储输出结果
        rows = [""]*numRows
        # 我们按V字来看这个题目
        # 一个V包含的字符个数就是 最高点和最低点以及中间两段
        # 和行数关联,numRows行每一竖条应该有numRows个字符,去除头尾就是(numRows-2)
        # 故一个V包含字符数为:2+2*(numRows - 2) = 2*numRows - 2
        n = 2*numRows - 2
        # 遍历字符串,枚举,直接获取到索引和索引对应的字符
        for i,char in enumerate(s):
            # % 取余,控制x在周期内[0, n]
            x = i % n 
            # 这里很智慧的就是利用min函数来自动转向
            # 当是下去的一笔时,x总小于n-x
            # 当是上去的一笔时,n-x总小于x
            rows[min(x, n-x)] += char
        # 利用join函数连接res列表里的每个元素
        # 到此解题完毕
        return "".join(rows)
(2)提交结果

image.png

测试数据:1157个测试用例

运行时间:52 ms,击败75%

内存消耗: 13 MB,击败42%

提交了很多次,也没有出现内存消耗很少的情况,所以这个提交检测排名还是有一定的偶然性的~不过,重要的是理解解题思路,加油。

五、疑惑

今日分享:如果你处于和我一样“比上不足,比下有余”的地方,我建议你两点:

1、承认。有人比我们优秀是正常的,没有人比我们优秀这才是坏事,如果你发现,你周围的人都不如你优秀,那说明,你现在的环境已经不适合你发展了,当然你可以跳出当前环境或者接触新环境带动当前环境(前者是技术人,后者是领导者)

2、做自己。完全没必要去和不优秀的人比较,也没必要和特别优秀的人较劲,做好自己,人生漫漫长路,你得一点一点积累,不因小事而停顿,不因大事而搓返。

六、结语

思想很复杂, 实现很有趣, 只要不放弃, 终有成名日。---《老表打油诗》

相关文章
|
3月前
蓝桥杯真题代码记录(保险箱
蓝桥杯真题代码记录(保险箱
30 1
蓝桥杯真题代码记录(保险箱
LeetCode150道面试经典题--赎金信(简单)
给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。
56 0
|
缓存 数据安全/隐私保护 C++
两道挺有意思的 CTF 题
两道挺有意思的 CTF 题
|
数据安全/隐私保护
密码学的心声题解
密码学的心声题解
144 0
密码学的心声题解
【力扣·每日一题】383. 赎金信 (模拟)
【力扣·每日一题】383. 赎金信 (模拟)
78 0
【力扣·每日一题】383. 赎金信 (模拟)
|
数据安全/隐私保护
【杂(瞎)谈(聊)】易经当中的密码学
看到这个标题,估计可能会有不少读者会有疑问,易经这不是个文学作品吗,怎么和数学相关的密码学给搞到一起了,这不是标题党蛤, 下面小Q来给大家聊聊在易经当中所体现的一些密码学的思想,有些资料来源也不太确定,我凭借记忆进行搜索的,如有错误还请各位读者海涵。
【杂(瞎)谈(聊)】易经当中的密码学
|
数据安全/隐私保护
听说这玩意可以防止否认 —— 数字签名
发送方发送消息的时候使用私钥对消息进行签名,接收方接收消息的时候使用公钥对签名进行验证即可确定发送者身份。因为签名只能由发送者的私钥完成,所以这个签名一定是由发送者签发的,这样就没有否认的问题了,这就是数字签名(Digital Signature)。
|
缓存 网络协议 NoSQL
面试总结之乐信(下)
六.TCP的三次握手四次挥手机制?
104 0
面试总结之乐信(下)
|
设计模式 存储 消息中间件
面试总结之乐信(上)
面试总结之乐信(上)
156 0
面试总结之乐信(上)