Try   HackMD

LeetCode 日記 #003:1071. 重新複習 GCD 為何物?了解字串最大公因數的特性

For two strings s and t, we say "t divides s" if and only if s = t + t + t + + t + t (i.e., t is concatenated with itself one or more times).Given two strings str1 and str2, return the largest string x such that x divides both str1 and str2.

這道題目的描述有幾個重點:

  1. t divides s: 在數學或計算機領域,t divides s 意思是 t 可以整除 s 的意思,代表字串 t 可以重複構成字串 s 且不會有任何剩餘的字元。
  2. If and only if: 這是在數學、邏輯學、計算機科學領域常用到的邏輯短語,通常縮寫為 iff。簡單來說就是一個「互為因果」的雙向關係,比如說假設 A 是我爸,那我一定是 A 的兒子。

也就是說題目會給兩個字串,要找出可以整除這兩個字串的最長字串,即「最大公因數」。

解題策略

而解法簡單分為三步驟:

  1. 排除邊界案例:檢查兩個字串是否存在最大公因數。判斷前需要先了解字串裡最大公因數的特性:

    若兩個有公因數的話,str1 + str2 = str2 + str1。
    不符合這個條件則返回空字串。

2.找出兩個字串長度的最大公因數,用歐基里德算法。

3.找出後取出任意字串匹配的最大公因長度。

完整題解

class Solution {
    public String gcdOfStrings(String str1, String str2) {
        if(!(str1 + str2).equals(str2 + str1)) {
            return "";
        }

        int gcdLength = gcd(str1.length(), str2.length());
        return str1.substring(0, gcdLength);
    }

    // 計算兩個數的最大公約數
    private int gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a % b);
    }
}

/**
- 思考最大公因數的本質:
對於字符串的最大公因數問題,有一個重要性質:
如果str1 + str2 == str2 + str1,則存在最大公因數;否則不存在。
- 最大公因數的長度就是 str1 和 str2 長度的最大公約數(數學上的GCD)。
 */

Complexity

引用 Claude AI。Cause I have no idea about analyze the time and space complexity of this problem. Still learning

時間複雜度: O(m + n)

  1. 字串拼接和比較:
    str1 + str2 和 str2 + str1 的操作涉及創建新的字符串,其時間複雜度為 O(m + n),其中 m 和 n 是兩個字符串的長度。比較兩個字符串是否相等需要 O(m + n) 時間。

  2. 計算最大公約數:
    使用歐幾里得算法計算 gcd 的時間複雜度為 O(log(min(m, n))),其中 m 和 n 是兩個數的大小。

  3. 提取子字符串:
    substring 操作的時間複雜度為 O(gcdLength),最壞情況下是 O(min(m, n))。

空間複雜度: O(m + n)

  1. 字符串拼接:
    str1 + str2 和 str2 + str1 創建了兩個新的字符串,每個長度為 m + n,因此空間複雜度為 O(m + n)。

  2. 遞迴調用:
    歐幾里得算法的遞迴深度為 O(log(min(m, n))),但通常這個遞迴深度很小,可以忽略不計。

  3. 結果字符串:
    最終返回的子字符串長度最多為 min(m, n),空間複雜度為 O(min(m, n))。

結論

時間複雜度:O(m + n),這可以簡化為 O(n),如果我們用 n 表示兩個字符串的總長度。
空間複雜度:O(m + n),主要來自於字符串拼接操作。

注意:如果不考慮字串拼接創建的臨時字符串(比如在某些語言或實現中可能有優化),那麼空間複雜度可能會降低,但在一般的 Java 實現中,它是 O(m + n) 而不是 O(1)。