Lintcode 29.交叉字串(101ms)
阿新 • • 發佈:2018-12-10
題目:給出三個字串:s1、s2、s3,判斷s3是否由s1和s2交叉構成。
樣例
比如 s1 = "aabcc" s2 = "dbbca"
- 當 s3 = "aadbbcbcac",返回 true.
- 當 s3 = "aadbbbaccc", 返回 false.
挑戰
要求時間複雜度為O(n^2)或者更好
1.思考一:
從s1和s2入手:求s1和s2的組合,太暴力。那就s3入手,第一反應就是對於s3中的每個字母肯定不是在s1就是在s2當中,那麼用一個for或while迴圈遍歷s3,每次迴圈判斷當前字母是否在s1或者s2當中,兩者都沒有就肯定不是“交叉字串”,返回False;如果迴圈結束就返回True。程式碼如下:
class Solution: """ @param s1: A string @param s2: A string @param s3: A string @return: Determine whether s3 is formed by interleaving of s1 and s2 """ def isInterleave(self, s1, s2, s3): # write your code here # i,j分別是指向s1和s2的“指標” i = 0 j = 0 for temp in s3: # 當前元素在s1當中 if i < len(s1) and temp == s1[i]: i += 1 # 當前元素在s2當中 elif j < len(s2) and temp == s2[j]: j += 1 else: return False return True
提交之後發現94.44%資料通過,沒有通過的資料太長了以至於無法知道自己哪兒錯了。
2.思考二:
在思考一的基礎上,發現每次迴圈中我都是先判斷s1中有沒有元素匹配,如果s2當中也有匹配元素呢,於是我列出了一個例子:
s1="aadcc" s2="dcbbca" s3="aadcbbcacc"
這是一個“交換字串”,如果用思路一走一遍,發現當i=4,j=0時進入else迴圈,即退出迴圈;錯誤很明顯,當s1與s3匹配到d時,繼續匹配,本來s2也可以匹配然而s1優先。
3.思考三:
解決上面的問題:問題出在else當中,不應該直接返回False,而應該回溯,回溯到一開始上一次匹配的地方,即s1[i]==s3[k]相等的地方,不過這次不能拿s1和s3比,而應該拿s2和s3比。程式碼如下:
class Solution:
"""
@param s1: A string
@param s2: A string
@param s3: A string
@return: Determine whether s3 is formed by interleaving of s1 and s2
"""
def isInterleave(self, s1, s2, s3):
# write your code here
i = 0
j = 0
k = 0
# 標記與s1還是s2比較
flag = 0
while k < len(s3):
if i < len(s1) and s3[k] == s1[i] and flag==0:
i += 1
k += 1
elif j < len(s2) and s3[k] == s2[j]:
j += 1
k += 1
flag = 0
# 回溯
else:
i = i-1
if i <= 0:
return False
k = k - 1
# 與s2比較
flag = 1
return True