去掉字串首尾逗號_劍指 Offer 20. 表示數值的字串 leetcode 劍指offer系列
阿新 • • 發佈:2020-12-27
技術標籤:去掉字串首尾逗號
點選專輯上方“藍字”關注我吧題目難度: 中等
原題連結[1]
今天繼續更新劍指 offer 系列, 這道題雖然難度是中等, 但通過率巨低, 應該是邊界情況比較多的原因. 而各種邊界條件也是面試比較愛考察的部分, 所以很值得一做
老樣子晚上 6 點 45 分準時更新公眾號 每日精選演算法題, 大家記得關注哦~ 另外在公眾號裡回覆 offer 就能看到劍指 offer 系列當前連載的所有文章了
題目描述
請實現一個函式用來判斷字串是否表示數值(包括整數和小數)。例如,字串"+100"、"5e2"、"-123"、"3.1416"、"0123"都表示數值,但"12e"、"1a3.14"、"1.2.3"、"+-5"、"-1E-16"及"12e+5.4"都不是。
題目樣例
示例
"0"=>true
"0.1"=>true
"abc"=>false
"1a"=>false
"2e10"=>true
"-90e3"=>true
"1e"=>false
"e3"=>false
"6e-1"=>true
"99e2.5"=>false
"53.5e93"=>true
"--6"=>false
"-+3"=>false
"95a54e53"=>false
題目思考
- 如何高效地處理各類情況?
- 邊界情況分為幾類?
解決方案
思路
分析
- 首先確定字串中允許有哪些字元, 以及各自需要滿足什麼條件 (如果面試遇到這種問題, 在模糊的地方一定要多溝通細節, 比如前導 0, 小數點位置等):
- 數字
- 數量沒有上限, 但至少需要有 1 個
- 無需處理前導 0 (因為題目用例裡 0123 是有效的)
e
- 只能有 1 個
- 不能是大寫 E
- 左右都必須有至少一個數字
+/-
e
的兩邊可以每邊最多出現 1 個- 都必須在開頭
.
- 只能有 1 個
- 只能出現在
e
之前 - 可以出現在開頭符號之後或數字之間
- 空格
- 只能出現在開頭和末尾
- 數字
- 根據上面分析, 一個自然的思路就是按照
e
將數字分為左右兩部分, 其中右邊唯一要求是不能有小數點, 別的和左邊一樣 - 這樣我們就可以將分析數字的部分提取成一個方法, 額外傳入一個 flag 表示是否可以有小數點, 然後分左右兩部分判斷即可~ 當然如果沒有
e
的話那直接判斷一次就行
實現
- 下面程式碼完全基於上述分析實現, 必要步驟都有詳細註釋
複雜度
- 時間複雜度
O(N)
- 只需要對每個字元判斷一次
- 空間複雜度
O(1)
- 只使用了常數個變數
程式碼
classSolution:
defisNumber(self,s:str)->bool:
#先要把首尾空格去掉
#然後判斷是否有e
#有的話分成左右兩部分check,左邊可以有小數,右邊不能有
#注意小數點可以位於任意位置..
#注意e之後不能有小數點
#注意每一部分判斷時需要保證至少有一個數字
s=s.strip()
defisValid(s,allowdot):
hasNum=False
hasDot=False
fori,cinenumerate(s):
ifc=='+'orc=='-':
#先判斷符號,如果不是在開頭,直接返回False
ifi!=0:
returnFalse
elifc=='.':
ifnotallowdot:
#當前不能有小數點,返回False
returnFalse
ifhasDot:
#已經有一個小數點了,返回False
returnFalse
hasDot=True
elifc.isnumeric():
#注意這裡至少需要滿足有一個數字
hasNum=True
else:
#其他字元都不滿足,直接返回False(包括e,因為e只允許有一個,有的話已經作為分隔符用掉了)
returnFalse
returnhasNum
e=s.find('e')
ife==-1:
#當前字串沒有e,直接判斷整體即可,也允許小數點
returnisValid(s,True)
else:
#分為左右部分分別判斷,左邊可以有小數點,右邊不行
returnisValid(s[0:e],True)andisValid(s[e+1:],False)
參考資料
[1]原題連結: https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/
你的每個贊和在看,我都喜歡!