9/8 刷题

本文详细介绍了LeetCode中的三道编程题目,分别是Z字形变换、整数反转和字符串转整数。针对每道题目,分别阐述了题目描述、解题思路并提供了相应的实现代码。Z字形变换通过设置方向标志实现;整数反转在Python中直接反转数字,注意溢出判断;字符串转整数利用有限自动机实现,转换状态表完成转换。
Z字形变换

题目来源:题目链接

题目描述

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

解题思路

这题如果没有找到技巧的话,很容易想歪,然后写又臭又长的代码,其实只要发现规律:我们只要设置一个代表方向的flag即可,因为他是Z字形的走,上下往复走

实现代码
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
            # 边界条件移动方向flag要改变
            if i == 0 or i == numRows-1:
                flag = -flag
            i += flag
        return "".join(res)


整数反转

链接:题目链接

题目描述

给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。

示例 1:

输入: 123
输出: 321
示例 2:

输入: -123
输出: -321
示例 3:

输入: 120
输出: 21
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。

解题思路

其实这题的关键点就是反转数字的时候可能会溢出的,但是python好像并没有这个问题,python可以存的数字大小和你的内存大小有关系,可以看看整数的实现链接
但我们依旧可以实现不会溢出的解题

实现代码
class Solution:
    def reverse(self, x: int) -> int:
        if -10<x<10:
            return x
        str_x = str(x)
        if str_x[0] != '-':
            str_x = str_x[::-1]
            x = int(str_x)
        else:
            str_x = str_x[:0:-1]
            x = int(str_x)
            x = -x
        return x if -2**31 < x < 2**31-1 else 0


字符串转整数

链接:题目链接

题目描述

请你来实现一个 atoi 函数,使其能将字符串转换成整数。

首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。接下来的转化规则如下:

如果第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字字符组合起来,形成一个有符号整数。
假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成一个整数。
该字符串在有效的整数部分之后也可能会存在多余的字符,那么这些字符可以被忽略,它们对函数不应该造成影响。
注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换,即无法进行有效转换。

在任何情况下,若函数不能进行有效的转换时,请返回 0 。

提示:

本题中的空白字符只包括空格字符 ’ ’ 。
假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,请返回 INT_MAX (231 − 1) 或 INT_MIN (−231) 。

解题思路–atoi,自动机

和剑指offer的一题很像,简直就一样,那题考的也是有限自动机,但是那题更难,因为那题是考浮点数的转换,还需要考虑小数点的情况,会复杂一些,自动机在正则表达式,匹配问题上面都有应用,原理思想是将所有可能的情况都列举出来,也算是一种暴力枚举方法吧
这题的状态可以分成4种:start,signed,in_number,end只有成功转换到in_number才算是符合题意,其余start和signed都是中间状态,而end是非法状态,还有四种类型的字符,就成了条件
所以转换表可以给出:

状态/条件space字符sign字符number字符other字符
startstartsignedin_numberend
signedendendin_numberend
in_numberendendin_numberend
endendendendend

状态转移表给出来了就好做了,

代码实现
class Solution:
    def myAtoi(self, s: str) -> int:
        automaton = Automaton()
        for c in s:
            automaton.get(c)
        return automaton.sign * automaton.ans




INT_MAX = 2**31 -1
INT_MIN = -2**31
class Automaton:
    def __init__(self):
        self.state = 'start'
        self.sign = 1
        self.ans = 0
        self.table = {
            'start':['start','signed','in_number','end'],
            'signed':['end','end','in_number','end'],
            'in_number':['end','end','in_number','end'],
            'end':['end','end','end','end']
        }
    def get_col(self,c):
        if c.isspace():
            return 0
        if c == '+' or c == '-':
            return 1
        if c.isdigit():
            return 2
        return 3
    def get(self,c):
        self.state = self.table[self.state][self.get_col(c)]
        if self.state == 'in_number':
            self.ans = self.ans*10 + int(c)
            # 这边要注意了,最小数字要变成正数在求min
            self.ans = min(self.ans,-INT_MIN) if self.sign == -1 else min(self.ans,INT_MAX)
        elif self.state == "signed":
            self.sign = 1 if c == "+" else -1


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值