【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
提示:
0 <= A.length <= 20000
0 <= B.length <= 20000
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_BSA,SB 的糖果。
如果愛麗絲給了糖果 xx,並且收到了糖果 yy,那麼鮑勃收到糖果 xx 並給出糖果 yy。那麼,我們一定有
S_A - x + y = S_B - y + xSA−x+y=SB−y+x
對於公平的糖果交換。這意味著
y = x + \frac{S_B - S_A}{2}y=x+2SB−SA
我們的策略很簡單。對於愛麗絲擁有的每個糖果 xx,如果鮑勃有糖果 y = x + \frac{S_B - S_A}{2}y=x+2SB−SA,我們就返回 [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)。)