1. 程式人生 > >Lintcode 29.交叉字串(101ms)

Lintcode 29.交叉字串(101ms)

題目:給出三個字串: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