解這題需要把題意仔細研究清楚,反正我試了好多次才明白的。
首先,考慮特殊情況:
1>兩個字串都爲空,返回true
2>當第一個字串不空,而第二個字串空了,返回false(因爲這樣,就無法
匹配成功了,而如果第一個字串空了,第二個字串非空,還是可能匹配成
功的,比如第二個字串是「a*a*a*a*」,由於‘*’之前的元素可以出現0次,
所以有可能匹配成功)
之後就開始匹配第一個字元,這裏有兩種可能:匹配成功或匹配失敗。但考慮到pattern
下一個字元可能是‘*’, 這裏我們分兩種情況討論:pattern下一個字元爲‘*’或
不爲‘*’:
①pattern下一個字元不爲‘*’:這種情況比較簡單,直接匹配當前字元。如果
匹配成功,繼續匹配下一個;如果匹配失敗,直接返回false。注意這裏的
「匹配成功」,除了兩個字元相同的情況外,還有一種情況,就是pattern的
當前字元爲‘.’,同時str的當前字元不爲‘\0’。
②pattern下一個字元爲‘*’時,稍微複雜一些,因爲‘*’可以代表0個或多個。
這裏把這些情況都考慮到:
a>當‘*’匹配0個字元時,str當前字元不變,pattern當前字元後移兩位,
跳過這個‘*’符號;
b>當‘*’匹配1個或多個時,str當前字元移向下一個,pattern當前字元
不變。(這裏匹配1個或多個可以看成一種情況,因爲:當匹配一個時,
由於str移到了下一個字元,而pattern字元不變,就回到了上邊的情況a;
當匹配多於一個字元時,相當於從str的下一個字元繼續開始匹配)
之後再寫程式碼就很簡單了。
# -*- coding:utf-8 -*-
class Solution:
# s, pattern都是字串
def match(self, s, pattern):
# 如果s與pattern都爲空,則True
if len(s) == 0 and len(pattern) == 0:
return True
# 如果s不爲空,而pattern爲空,則False
elif len(s) != 0 and len(pattern) == 0:
return False
# 如果s爲空,而pattern不爲空,則需要判斷
elif len(s) == 0 and len(pattern) != 0:
# pattern中的第二個字元爲*,則pattern後移兩位繼續比較
if len(pattern) > 1 and pattern[1] == '*':
return self.match(s, pattern[2:])
else:
return False
# s與pattern都不爲空的情況
else:
# pattern的第二個字元爲*的情況
if len(pattern) > 1 and pattern[1] == '*':
# s與pattern的第一個元素不同,則s不變,pattern後移兩位,相當於pattern前兩位當成空
if s[0] != pattern[0] and pattern[0] != '.':
return self.match(s, pattern[2:])
else:
# 如果s[0]與pattern[0]相同,且pattern[1]爲*,這個時候有三種情況
# pattern後移2個,s不變;相當於把pattern前兩位當成空,匹配後面的
# pattern後移2個,s後移1個;相當於pattern前兩位與s[0]匹配
# pattern不變,s後移1個;相當於pattern前兩位,與s中的多位進行匹配,因爲*可以匹配多位
return self.match(s, pattern[2:]) or self.match(s[1:], pattern[2:]) or self.match(s[1:], pattern)
# pattern第二個字元不爲*的情況
else:
if s[0] == pattern[0] or pattern[0] == '.':
return self.match(s[1:], pattern[1:])
else:
return False
解題思路:
解法:
這題難點只有邊界問題的考慮,所以最好一開始就考慮全麪點,省的不斷的調bug,給面試官不好的印象。
那麼結合上圖中給的提示,大概有以下幾種情況:
e/E之前和e/E之後可以看做是兩個部分。
e/E之前的部分:
+/-只能在頭部出現,且只能出現一次;
數位直接continue
非e/E的字元出現,直接return False
頭部如果出現".",直接return False
非頭部如果出現一次".",後面如果再出現".",則return False
e/E之後的部分:
+/-只能在頭部出現,且只能出現一次;
如果有".",直接return False
如果觸發e/E之後的部分,e/E後沒有其他數位了,要return False
其他符號也要return False
以上即爲全部的邊界條件,通過多個flag去進行控制。
# -*- coding:utf-8 -*-
class Solution:
# s字串
def isNumeric(self, s):
# write code here
flag = 0 # 是否有e/E,預設沒有爲0
_flag = 0 # e/E後的加/減號的flag
dot_flag = 0 # e/E前的「.」的flag
i = 0
count = 0 # 判斷觸發e/E後是否仍有數位
if s[i] == '+':
i += 1
elif s[i] == '-':
i += 1
elif s[i] == '.': # 頭部如果出現".",直接return False
return False
for item in s[i:]:
if flag == 0: # e/E之前的部分
if dot_flag == 1 and item == '.':
return False
if '0' <= item <= '9': # 數位直接continue
continue
if item == 'e' or item == 'E': # 觸發e/E後的部分
flag = 1
continue
if item == '.':
# 非頭部如果出現一次".",後面如果再出現".",則return False
dot_flag = 1
continue
else:
return False
else:
count += 1
# 如果觸發e/E之後的部分,e/E後沒有其他數位了,要return False
if _flag == 1 and (item == '-' or item == '+'):
# +/-只能在頭部出現,且只能出現一次;
return False
if item == '+':
_flag = 1
continue
if item == '-':
_flag = 1
continue
if item == '.': # 有"."直接False
return False
if '0' <= item <= '9':
continue
else:
return False
if flag == 1 and count == 0:
return False
return True
Python中,lambda函數也叫匿名函數,及即沒有具體名稱的函數,它允許快速定義單行函數,類似於C語言的宏,可以用在任何需要函數的地方。這區別於def定義的函數。
filter 表示過濾器
# -*- coding:utf-8 -*-
class Solution:
def __init__(self):
self.s = ""
# 返回對應char
def FirstAppearingOnce(self):
# write code here
res = list(filter(lambda x:self.s.count(x)==1, self.s))
if res:
return res[0]
else:
return "#"
# return res [0] if res else "#"
def Insert(self, char):
# write code here
self.s += char