iT邦幫忙

0

解LeetCode的學習筆記Day65_Valid Number

LFI 2025-11-25 21:58:38324 瀏覽
  • 分享至 

  • xImage
  •  

今天是紀錄LeetCode解題的第六十五天
是一題困難題

第六十五題題目:Given a string s, return whether s is a valid number.

For example, all the following are valid numbers: "2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10", "-90E3", "3e+7", "+6e-1", "53.5e93", "-123.456e789", while the following are not valid numbers: "abc", "1a", "1e", "e3", "99e2.5", "--6", "-+3", "95a54e53".

Formally, a valid number is defined using one of the following definitions:

  1. An integer number followed by an optional exponent.
  2. A decimal number followed by an optional exponent.

An integer number is defined with an optional sign ' - ' or ' + ' followed by digits.

A decimal number is defined with an optional sign ' - ' or ' + ' followed by one of the following definitions:

  1. Digits followed by a dot ' . '.
  2. Digits followed by a dot ' . ' followed by digits.
  3. A dot ' . ' followed by digits.

An exponent is defined with an exponent notation ' e ' or ' E ' followed by an integer number.

The digits are defined as one or more digits.

給定一個字串s,回傳它是否是有效數字,例如,以下字串皆是有效數字:"2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10", "-90E3", "3e+7", "+6e-1", "53.5e93", "-123.456e789",而以下字串不是有效數字:"abc", "1a", "1e", "e3", "99e2.5", "--6", "-+3", "95a54e53"

以下是有效數字的定義:

  1. 一個整數後面可以跟著一個可選的指數
  2. 一個十進制數後面可以跟著一個可選的指數

整數由可選符號' - '或' + '後面跟著數字定義

十進制數可以用可選的符號' - '或' + ' 以下定義之一來定義:

  1. 數字後面跟一個點' . '
  2. 數字後面跟一個點' . '再跟數字
  3. 一個點' . '後面跟著數字

指數可以用指數符號**' e '或' E '表示,後面也可以跟著整數**

數字定義為一個數字或多個數字

解題思路

類別 規則
小數點 至少要有一個數字(可在小數點前或後),ex:0.9、.9、2.皆合法
e/E 表示科學記號,後面必須跟整數 ,ex:3e4合法、1e(e後面沒有數字不合法)
正負號 只能出現在開頭或 e/E 之後 ,ex:-3、1e-3(表示0.001)皆合法

以上大概是有效符號規則判斷統整

首先我們在程式裡宣告四個指標分別為

  • seen_digit:是否有至少一個數字
  • seen_dot:是否有小數點
  • seen_exp:是否有e/E
  • digit_after_exp:e/E之後是否有數字(必須有)

接著掃描整個字串

  1. 當遇到數字時將seen_digit設為True,並判斷是否出現過e/E(if seen_exp),如果e/E出現過,將digit_after_exp設為True
  2. 當遇到正負號時,因為正負號只能出現在開頭或e/E的後面,所以只要判斷如果正負號不在開頭或前一個字元不是e/E則直接回傳False
  3. 當遇到小數點時,如果之前已經有小數點或e\E出現則回傳False,因為小數點只能出現一次,且不能出現在e/E後面
  4. 當遇到e\E時,如果之前已經有e\E出現或沒有數字出現則直接回傳False,因為e/E只能出現一次,且前面必須有數字,接著重置digit_after_exp = False
  5. 剩下遇到其他符號皆不合法所以回傳False
  6. 最後回傳seen_digit and digit_after_exp,因為一定要包含數字,而digit_after_exp也是判斷是否有沒有數字出現(只是更嚴格指定為在e\E後面出現),如果e\E沒有在字串裡,本身這個指標是True

程式碼

class Solution:
    def isNumber(self, s: str) -> bool:
        s = s.strip()
        seen_digit = False
        seen_exp = False
        seen_dot = False
        digit_after_exp = True #初始True,表示沒有遇到e/E,只要有數字就合法

        for i, ch in enumerate(s):
            if ch.isdigit():
                seen_digit = True
                if seen_exp: #有遇到自然指數
                    digit_after_exp = True #遇到數字,表示e/E後有數字

            elif ch in ['+', '-']:
                #正負號只能出現在開頭或e/E後面
                if i > 0 and s[i-1] not in ['e', 'E']:
                    return False

            elif ch == '.':
                #小數點只能出現一次,且不能出現在e/E後面
                if seen_dot or seen_exp:
                    return False
                seen_dot = True

            elif ch in ['e', 'E']:
                #e/E只能出現一次,且前面必須有數字
                if seen_exp or not seen_digit:
                    return False
                seen_exp = True
                digit_after_exp = False  #遇到e/E,重置標誌,等有遇到數字再設定為True
            else: #其餘符號全部都不合法
                return False
        return seen_digit and digit_after_exp

圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言