算法修煉之路—【字符串】Leetcode 680 重複疊加字符串匹配

題目描述

給定兩個字符串AB,尋找重複疊加字符A的最小次數,使得字符串B成爲疊加後的字符串A的子串,如果不存在則返回-1.

示例:

輸入: A = “abcd”, B = “cdabcdab”
輸出: 3
解釋: A重複疊加三遍後爲"abcdabcdabcd",此時B是其子串; A 重複疊加兩邊後爲“abcdabcd”,B並不是其子串。

注意: AB字符串的長度在110000區間範圍內。

思路分析

題目難度爲簡單 ,這裏簡化題目意思就是輸入字符串存在子母串關係前提下,如何判斷A的最小重複次數,如圖1,圖2 所示,這裏我們可以將情況分爲兩種:

  1. B佔據kA的中間部分;
  2. B至少佔據kA一端(開頭或結尾)字符;
    在這裏插入圖片描述
    圖1 情況1示意圖

在這裏插入圖片描述
圖2 情況2示意圖

這裏,我們進一步分析可知,若BA的子串,則會在疊加A後的子串長度小於等於2倍B字符串長度內檢測到,故這裏直接給出代碼核心部分:

代碼片1

		StringBuiler strs = new StringBuilder(a);
		int res = 1;
		
        while(strs.length() < b.length()*3){ // or <= b.length() * 2
            if(strs.indexOf(b) >= 0)
                return res;
            else{
                strs.append(a);
                res++;
            }
        }

情況完善

在上面的思考過程中,我們會發現僅適用於a.length() <= b.length()的情況,如果a.length() > b.length(),我們需要判斷當strs.length() < a.length()*3的情況(這裏不做詳細說明,可自行繪圖):

  1. BA的中間子串,則在首次while循環(僅疊加了一次)時,返回1;
  2. B佔據A的至少一端,則至多在第二次while循環(疊加了兩次)時,則會發現;

即當A.length() > B.length()時,不存在當B確實爲A,但兩次疊加A後無法檢測的情況,故這裏while循環設置爲while(strs.length() < a.length()*3)。這時核心代碼變成:

代碼片2

        while(strs.length() < a.length()*3){ // or <= a.length() * 2
            if(strs.indexOf(b) >= 0)
                return res;
            else{
                strs.append(a);
                res++;
            }
        }

情況合併

此時,我們比較代碼片1代碼片2,試圖將其進行規整,我們發現while循環條件均爲strs.length() < x * 3,這裏的x爲輸入字符串a,b的最長者,則我們可以設置一基準長度baseLen,將while循環條件變量化:

        int baseLen = Math.max(a.length(), b.length());
        
        while (strs.length() < baseLen * 3) {
            if (strs.indexOf(b) >= 0) {
                return res;
            } else {
                strs.append(a);
                res++;
            }
        }

進一步節省空間,我們直接將變量baseLen省略,則有最終的解題代碼:

解題代碼

    public static int solution(String a, String b) {
    
		int res = 1;
        StringBuilder strs = new StringBuilder(a);
        
        while (strs.length() < 3 * Math.max(a.length(), b.length())) {
        
            if (strs.indexOf(b) >= 0) {
                return res;                
            } else {
                strs.append(a);
                res++;
            }
        }

        return -1;

    }

複雜度分析

我們設n,mA,B的字符創長度

時間複雜度: 檢測B是否爲子串時,其時間複雜度爲O(m)strs的長度最長爲2max(n, m),故時間複雜度爲O(m*max(n, m));
空間複雜度: 我們藉助了StringBuiler strs的輔助,且最長爲2max(n, m),故空間複雜度爲O(max(n, m));

Github源碼

完整可運行文件請訪問GitHub

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章