LeetCode Question 8: Convert String to Integer (Python3 Solution)

1: Problem description

Source: LeetCode

Difficulty: Moderate


Details of the problem:
Since the description of the topic of Lituo itself is not clear enough, I will use my own words to describe the problem.
Given a string s, read the integers in it, but must be of the following form:

  1. When the number is not read for the first time , the space character at the beginning of the character “ ”can be ignored. “+”The character represents a positive integer, and "-"the character represents a negative integer. If there are no these two, the default is a positive symbol ;
  2. When the number is read for the first time , it will stop when it encounters non-numeric characters in the future;
  3. If the number read has exceeded 2 31 2^{31}231 , return2 31 2^{31}231 ; if less than− 2 31 − 1 -2^{31}-12311 , it returns− 2 31 − 1 -2^{31}-12311
  4. If no numbers have been read in when stopped, returns as0

case:

Input: “”
Output: 0
Explanation: No numbers were read

input: “+1”
output:1

Input: “+1+1”
Output: 1
Explanation: “+”Stop reading according to the second condition when the second one is read

Input: “ +1+”
Output: 1
Interpretation: According to clause 1, clause 2 returns1

Input: “ ++1+”
Output: 0
Explanation: According to Article 1, Article 2, Article 4, returns 0

Input: “2147483648”
Output: ”2147483647“
Explanation: According to clause 3, out of bounds


2: Problem analysis

2.1 Time Complexity and Space Complexity

Before actually starting to introduce various algorithms, first show their respective time complexity and space complexity in tabular form, where nnn represents the stringsslength of s .

algorithm time complexity space complexity
direct method O ( n ) O(n)O ( n ) O(1) O(1)O(1)
regular expression method O ( n ) O(n)O ( n ) O(1) O(1)O(1)
automaton O ( n ) O(n)O ( n ) O(1) O(1)O(1)

2.2 Direct method

The process is as follows:

  1. First remove the spaces on the left
  2. Empty string, returns 0
  3. i n d e x index index i i i respectively represent the number of numbers read and the subscript of the current character
  4. If the 0th character is ”+“or ”-“, change signthe value of the sign variable
  5. If the current iii characters are not numbers, then stop;
  6. If the current iii characters are numbers, then judge the length of the current integer, because2 31 2^{31}2The length of 31 is 10, so if it is less than 10, there is no need to consider the problem of crossing the boundary; if it is greater than or equal to 10, it needs to be judged.

2.2.1 Code

Since the previous problem details are described in detail, the code is given directly:

def myAtoi(s: str) -> int:
    s = s.lstrip() # 去左边空格
    sign = 1
    num = 0
    MAX = 2 ** 31 - 1
    MIN = -2 ** 31
    i = 0 # 字符索引
    index = 0 # 数字索引
    # 排除空字符串
    if not s:
        return 0
       
    # 符号
    if s[0] == '+':
        i += 1
    elif s[0] == '-':
        sign = -1
        i += 1

    while i < len(s):
        if s[i].isnumeric():
            index += 1
            num = num * 10 + eval(s[i])
            
            # 数字长度超过或者等于10,则要考虑是否超过了界限
            if index >= 10:
                if num * sign >= MAX:
                    return MAX
                elif num * sign <= MIN:
                    return MIN
            i += 1
        else:
            break
    return sign * num

Time complexity is O ( n ) O(n)O ( n ) , the space complexity isO ( 1 ) O(1)O(1)

2.3 Regular expression method

The process is as follows:

  1. First remove spaces to the left of the character

  2. Use regular expressions to match one of the following two forms:

    (1) The beginning of the positive and negative signs + numbers
    (2) Pure numbers

  3. Convert the above result to int

  4. Then limit the value of type int to 32 bits.

2.3.1 Code

def myAtoi2(s: str) -> int:
    import re
    INT_MAX = 2147483647
    INT_MIN = -2147483648
    s = s.lstrip()      #清除左边多余的空格
    num_re = re.compile(r'^[\+\-]?\d+')   #设置正则规则
    num = num_re.findall(s)   #查找匹配的内容
    num = int(*num) #由于返回的是个列表,解包并且转换成整数
    return max(min(num,INT_MAX),INT_MIN)    #返回值

r'^[\+\-]?\d+'Medium target:

  • ‘^’Indicates that it starts with the following character
  • '[\+\-]'Indicates a positive sign or a negative sign, ‘\’indicating an escape character
  • '?'Indicates matching the previous string 0 or 1 time, that is to say, the front sign can only appear 0 or 1 time
  • ‘\d+’means ‘\d’match 0-9, and '+'means match the previous string 1 or more times

It can be known that the string obtained by such a matching rule can only be one or not found, so the findallreturned result numcan only be a list with a string or an empty list.
For int(*num):

  • When numit is a list of strings, such as [ '-123'],that int(*num)isint('-123')=123
  • When numan empty list, int(*num)=int(), int()defaults to0

Then use min()and max()limit the range.

The time complexity of the regular expression method is O ( n ) O(n)O ( n ) , the space complexity isO ( 1 ) O(1)O(1)

2.4 Automata

An automaton is a machine that, given symbolic input, "jumps" through a sequence of states according to a transition function (expressed as a table).

According to the conditions in Section 1, we construct the state transition in the figure below. Image source .
insert image description here
There are the following states:

  1. start
  2. end;
  3. signed;
  4. in_number;

For start->signedexample, the state is entered only when the sign is read at the beginning signed.

Similarly, the following table can also be used to represent the state transition function ( table source ), and the symbols include empty, positive and negative signs, numbers, and other four types.
insert image description here

2.4.1 Code

Next, use code to implement this state transition function:

  1. Use tablethe form constructed above;
  2. table[‘开始状态’]['列索引']Get the state after the next transition, the initial state is ‘start’;
  3. The column index is obtained by the current character ( get_col);
  4. in_numberWhen the state after the transfer is , judge whether it is out of bounds;
  5. ‘signed’When the state after the transfer is , the sign is reassigned;
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)]  # table[开始状态][列索引]
        if self.state == 'in_number':
            self.ans = self.ans * 10 + int(c)
            self.ans = min(self.ans, INT_MAX) if self.sign == 1 else min(self.ans, -INT_MIN)
        elif self.state == 'signed':
            self.sign = 1 if c == '+' else -1


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

Time complexity is O ( n ) O(n)O ( n ) , the space complexity isO ( 1 ) O(1)O(1)

Guess you like

Origin blog.csdn.net/weixin_43490422/article/details/126585568