【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)。)

猜你喜欢

转载自blog.csdn.net/m511655654/article/details/82592233