1. 程式人生 > >【leetcode】python演算法題庫

【leetcode】python演算法題庫

859. 親密字串

給定兩個由小寫字母構成的字串 A 和 B ,只要我們可以通過交換 A 中的兩個字母得到與 B 相等的結果,就返回 true ;否則返回 false 。

 

示例 1:

輸入: A = "ab", B = "ba"
輸出: true

示例 2:

輸入: A = "ab", B = "ab"
輸出: false

示例 3:

輸入: A = "aa", B = "aa"
輸出: true

示例 4:

輸入: A = "aaaaaaabc", B = "aaaaaaacb"
輸出: true

示例 5:

輸入: A = "", B = "aa"
輸出: false

 

提示:

  1. 0 <= A.length <= 20000
  2. 0 <= B.length <= 20000
  3. A 和 B 僅由小寫字母構成。

程式碼:

class Solution:
    def buddyStrings(self, A, B):
        """
        :type A: str
        :type B: str
        :rtype: bool
        """
        a = list(A)
        b = list(B)
        # 字串均為空
        if not A and not B:
            return False
        # 字串長度不等
        if len(A) != len(B):
            return False
        # 字串長度相等,字元相同
        if A == B:
            if len(set(a)) < len(a):
                return True
            else:
                return False
        # 字串長度相等,字元不同
        count = 0
        temp1 = []
        temp2 = []
        for i in range(len(A)):
            if a[i] != b[i]:
                count += 1
                temp1.append(a[i])
                temp2.append(b[i])
            else:
                continue
        if count > 2 :
            return False
        elif count == 2 and temp1[0] == temp2[1] and temp1[1] == temp2[0]:
            return True
        else:
            return False

if __name__ == '__main__':
    A = "abab"
    B = "abab"
    out = Solution()
    output = out.buddyStrings(A, B)
    print(output)

解決方案

方法:情況列舉

思路

如果 A[i] == B[i],我們就說 i 是匹配的,否則稱 i 是不匹配的。親密字串幾乎是完全匹配的,因為一次交換隻會影響到兩個索引。

如果交換 A[i] 和 A[j] 可以證明 A 和 B 是親密字串,那麼就有 A[i] == B[j] 以及 A[j] == B[i]。 這意味著在 A[i], A[j], B[i], B[j] 這四個自由變數中,只存在兩種情況:A[i] == A[j]

 或 A[i] != A[j]

演算法

讓我們來看看這些情況。

在 A[i] == A[j] == B[i] == B[j] 的情況下,字串 A 與 B 相等。因此,如果 A == B,我們應當檢查每個索引 i 以尋找具有相同值的兩個匹配。

在 A[i] == B[j], A[j] == B[i], (A[i] != A[j]) 的情況下,其餘索引是相匹配的。所以如果 A 和 B 只有兩個不匹配的索引(記作 i 和 j),我們應該檢查並確保等式 A[i] == B[j] 和 A[j] == B[i] 成立。

程式碼:

class Solution(object):
    def buddyStrings(self, A, B):
        if len(A) != len(B): return False
        if A == B:
            seen = set()
            for a in A:
                if a in seen:
                    return True
                seen.add(a)
            return False
        else:
            pairs = []
            for a, b in itertools.izip(A, B):
                if a != b:
                    pairs.append((a, b))
                if len(pairs) >= 3: return False
            return len(pairs) == 2 and pairs[0] == pairs[1][::-1]

888. 公平的糖果交換

愛麗絲和鮑勃有不同大小的糖果棒:A[i] 是愛麗絲擁有的第 i 塊糖的大小,B[j] 是鮑勃擁有的第 j 塊糖的大小。

因為他們是朋友,所以他們想交換一個糖果棒,這樣交換後,他們都有相同的糖果總量。(一個人擁有的糖果總量是他們擁有的糖果棒大小的總和。)

返回一個整數陣列 ans,其中 ans[0] 是愛麗絲必須交換的糖果棒的大小,ans[1] 是 Bob 必須交換的糖果棒的大小。

如果有多個答案,你可以返回其中任何一個。保證答案存在。

 

示例 1:

輸入:A = [1,1], B = [2,2]
輸出:[1,2]

示例 2:

輸入:A = [1,2], B = [2,3]
輸出:[1,2]

示例 3:

輸入:A = [2], B = [1,3]
輸出:[2,3]

示例 4:

輸入:A = [1,2,5], B = [2,4]
輸出:[5,4]

提示:

  • 1 <= A.length <= 10000
  • 1 <= B.length <= 10000
  • 1 <= A[i] <= 100000
  • 1 <= B[i] <= 100000
  • 保證愛麗絲與鮑勃的糖果總量不同。
  • 答案肯定存在。

程式碼:

class Solution:
    def fairCandySwap(self, A, B):
        """
        :type A: List[int]
        :type B: List[int]
        :rtype: List[int]
        """
        C = [None, None]
        suma = sum(A)
        sumb = sum(B)
        d = (suma - sumb)/2
        ret = []
        flag = 0
        for i in range(len(A)):
            for j in range(len(B)):
                if A[i] - B[j] == d:
                    C[0] = A[i]
                    C[1] = B[j]
                    flag = 1
                    if flag > 0:
                        return C
        return C   

if __name__ == '__main__':
    A = [2]
    B = [1, 3]
    out = Solution()
    output = out.fairCandySwap2(A, B)
    print(output)

解決方案


方法:方程求解

思路

如果愛麗絲交換糖果 x,她將會期待交換一些特定量的糖果 y 回來。

演算法

設愛麗絲和鮑勃分別總計有 S_A, S_BS​A​​,S​B​​ 的糖果。

如果愛麗絲給了糖果 xx,並且收到了糖果 yy,那麼鮑勃收到糖果 xx 並給出糖果 yy。那麼,我們一定有

 

S_A - x + y = S_B - y + xS​A​​−x+y=S​B​​−y+x

對於公平的糖果交換。這意味著

 

y = x + \frac{S_B - S_A}{2}y=x+​2​​S​B​​−S​A​​​​

我們的策略很簡單。對於愛麗絲擁有的每個糖果 xx,如果鮑勃有糖果 y = x + \frac{S_B - S_A}{2}y=x+​2​​S​B​​−S​A​​​​,我們就返回 [x,y][x,y]。我們在常量時間內使用集 Set 結構來檢查Bob是否擁有所需的糖果 yy。

程式碼:

class Solution(object):
    def fairCandySwap(self, A, B):
        Sa, Sb = sum(A), sum(B)
        setB = set(B)
        for x in A:
            if x + (Sb - Sa) / 2 in setB:
                return [x, x + (Sb - Sa) / 2]

複雜度分析

  • 時間複雜度:O(A\text{.length} + B\text{.length})O(A.length+B.length)。

  • 空間複雜度:O(B\text{.length})O(B.length),setB 用去的空間。(通過使用 if 語句,我們可以將其改進到 \min(A\text{.length}, B\text{.length})min(A.length,B.length)。)