1. 程式人生 > 其它 >leetcode 8 思路及code(帶註釋)

leetcode 8 思路及code(帶註釋)

技術標籤:leetcodepythonleetcodepython字串正則表示式

題目分析


在這裡插入圖片描述
以上是三種方法的提交結果,第一個為官方解答DFA,第二個為自己手寫的if-else,最後一個為正則匹配。
題目並不難,函式主要就是解決字串轉數字

  • 自己想到的就是手寫,一輪迴圈,但是邊界需要做判斷
  • 看題解有用正則表示式解決的,寫法比較簡答,效率也並不高
  • 學過《形式語言與自動機》這門課,感覺也沒什麼用處,但是看官方題解,用到了DAF(確定的有限狀態自動機),有種學有所用的感覺

解題


  • 方法一
  • 解題思路
  1. 去掉開頭的空格字元
  2. 符號判斷,正負數,需要注意特殊情況 [+1 -> 1; ±1 -> 0]
  3. 迴圈找到數字邊界
  4. 轉為整數,輸出,注意題目邊界要求
  • code
    python3版本,主要利用了字串的切片操作
class Solution:
    def myAtoi(self, s: str) -> int:
        maxValue = 2 ** 31
        i = 0
        s = s.lstrip() # 去字串最左端空格

        if s == '':  # 異常處理空字串
            return 0

		# 處理符號
        sign = 1
        if s[0] == '-':
            sign =
-1 i = 1 if s[0] == '+': i = 1 # 查詢字元中數字開頭結尾 start = i while i < len(s) and '0' <= s[i] <= '9': i += 1 if start == i: return 0 x = sign * int(s[start:i]) if -maxValue <= x < maxValue: return
x elif x < -maxValue: return -maxValue else: return maxValue - 1

  • 方法二
  • 解題思路
  1. 正則表示式提取
  2. 符號判斷,正負數,需要注意特殊情況 [+1 -> 1; ±1 -> 0]
  3. 迴圈找到數字邊界
  4. 轉為整數,輸出,注意題目邊界要求
  • code
    python3版本,主要利用了字串的切片操作
class Solution2:
    def myAtoi(self, s: str) -> int:
        '''
        1. s.lstrip() 刪除字串最左端空格字元
        2. 正則表示式 ^[\+\-]?\d+, ^匹配字串開頭字元, [\+\-]?匹配0個或者一箇中括號中的字元,\d表示數字字元,+表示至少一個
        3. re.findall返回列表, 前面的*是解包的意思,由於取第一個數字串,故列表中只有一個元素,解包即去掉列表轉為字串,但是這裡不能取
        4. int(*re.findall),找到即返回數字,否則就是0
        5. 處理越界,先與最大取最小值,在與最小值取最大值
        :param s:
        :return:
        '''
        return max(min(int(*re.findall('^[\+\-]?\d+', s.lstrip())), 2 ** 31 - 1), -2 ** 31) 

  • 方法三(具體圖見官方解答)
  • 解題思路
  1. 狀態轉移圖
  2. 狀態轉移表
  3. 程式表示狀態轉移表
  • code
    python3版本,主要利用了字串的切片操作
class DFA:
    def __init__(self):
        '''
        繪製狀態轉移表
        state為當前狀態,初始為start
        sign為正負號標記
        ans為最終答案
        state_table為狀態轉移表
        '''
        self.state = 'start'
        self.sign = 1
        self.ans = 0
        self.state_table = {
            'start': ['start', 'signed', 'in_num', 'end'],
            'signed': ['end', 'end', 'in_num', 'end'],
            'in_num': ['end', 'end', 'in_num', 'end'],
            'end': ['end', 'end', 'end', 'end']
        }

    def get_col_state(self, char):
        '''
        對應每個列表下標
        :param char:
        :return:
        '''
        if char.isspace():
            return 0
        elif char == '-' or char == '+':
            return 1
        elif char.isdigit():
            return 2
        else:
            return 3

    def get_current_state(self, char):
        '''
        獲取當前狀態並更新狀態
        獲取當前值,儲存符號狀態
        :param char:
        :return:
        '''
        self.state = self.state_table[self.state][self.get_col_state(char)]
        if self.state == 'in_num':
            self.ans = self.ans * 10 + int(char)
            self.ans = min(self.ans, MAX_SIGNED) if self.sign == 1 else min(self.ans, -MIN_SIGNED)
        if self.state == 'signed':
            self.sign = -1 if char == '-' else 1


class Solution:
    def myAtoi(self, s: str) -> int:
        dfa = DFA()
        for c in s:
            dfa.get_current_state(c)
        return dfa.sign * dfa.ans

參考解題思路