判斷一個字符串是否為合法數值。合法數值包括:整數、小數、科學計數法(含 e/E)、可選正負號、可選前後空格。
範例:
輸入: " -3.2e-23 "
輸出: true
合法: "0.1", "2e10", "-90e3", "3.", ".5", "6e-1"
非法: "abc", "1a", "1e", "e3", "99e2.5", "--6", "-+3", "95a54e53"
題目未給出嚴格定義,需通過測試用例歸納規則。採用單次遍歷 + 多標記位法:
strip() 去除首尾空格+/-)e 前部分:數字、小數點、小數點後數字 → 標記 is_numerice/E 且前部分合法:處理指數部分(可選符號 + 數字) → 標記 is_expis_numeric && is_exp && 全串遍歷完時間複雜度:O(n),空間複雜度:O(1)。
class Solution:
def isNumber(self, s):
"""
:type s: str
:rtype: bool
"""
s = s.strip()
n = len(s)
i = 0
# 符號
if i < n and (s[i] == '+' or s[i] == '-'):
i += 1
is_numeric = False
is_exp = True # 無 e 時默認 true
# e 前的數字
while i < n and s[i].isdigit():
i += 1
is_numeric = True
# 小數點及後續數字
if i < n and s[i] == '.':
i += 1
while i < n and s[i].isdigit():
i += 1
is_numeric = True
# 科學計數法 e/E
if is_numeric and i < n and (s[i] == 'e' or s[i] == 'E'):
i += 1
is_exp = False # 有 e 時需驗證指數部分
if i < n and (s[i] == '+' or s[i] == '-'):
i += 1
while i < n and s[i].isdigit():
i += 1
is_exp = True
return is_numeric and is_exp and i == n
# 測試
if __name__ == "__main__":
sol = Solution()
assert sol.isNumber("3.e-23") == True
assert sol.isNumber(".2e81") == True
assert sol.isNumber("2e10") == True
assert sol.isNumber(" 0.1") == True
assert sol.isNumber("1 b") == False
assert sol.isNumber("3-2") == False
assert sol.isNumber("abc") == False
assert sol.isNumber("") == False
assert sol.isNumber(".") == False
assert sol.isNumber(".1") == True
print("所有測試通過")
is_numeric 確保主體有數字,is_exp 確保 e 後有數字. 前後可無數字(但至少一邊有),e 後不可有小數點,首尾空格合法這道題被稱為「面試殺手」,關鍵在於完整覆蓋邊界情況而非演算法複雜度。掌握「分段驗證 + 標記位」模式,可應對各類字符串格式驗證問題。