Given two strings A and B of lowercase letters, return true if you can swap two letters in A so the result is equal to B, otherwise, return false.
Swapping letters is defined as taking two indices i and j (0-indexed) such that i != j and swapping the characters at A[i] and A[j]. For example, swapping at indices 0 and 2 in "abcd" results in "cbad".
 
Example 1:
Input: A = "ab", B = "ba"
Output: true
Explanation: You can swap A[0] = 'a' and A[1] = 'b' to get "ba", which is equal to B.

Example 2:
Input: A = "ab", B = "ab"
Output: false
Explanation: The only letters you can swap are A[0] = 'a' and A[1] = 'b', which results in "ba" != B.

Example 3:
Input: A = "aa", B = "aa"
Output: true
Explanation: You can swap A[0] = 'a' and A[1] = 'a' to get "aa", which is equal to B.

Example 4:
Input: A = "aaaaaaabc", B = "aaaaaaacb"
Output: true

Example 5:
Input: A = "", B = "aa"
Output: false

 
Constraints:

0 <= A.length <= 20000
0 <= B.length <= 20000
A and B consist of lowercase letters.

Source: leetcode | Difficulty: EASY
Tags: String algorithms

Data structures

Starter code: class Solution:
    def buddyStrings(self, A: str, B: str) -> bool:
        

Solutions:
class Solution:

	def buddyStrings(self, A: str, B: str) -> bool:
		if len(A) != len(B):
			return False
		if len(A) < 2:
			return False
		if A == B:
			cnt = Counter(A)
			return bool([v for v in cnt.values() if v > 1])
		diffs = []
		for (i, a) in enumerate(A):
			if a != B[i]:
				diffs.append(i)
		if len(diffs) == 2:
			(i, j) = diffs
			return A[i] == B[j] and A[j] == B[i]
		return False


class Solution:

	def buddyStrings(self, A, B):
		if len(A) != len(B) or set(A) != set(B):
			return False
		if A == B:
			return len(A) - len(set(A)) >= 1
		else:
			indices = []
			counter = 0
			for i in range(len(A)):
				if A[i] != B[i]:
					counter += 1
					indices.append(i)
				if counter > 2:
					return False
			return A[indices[0]] == B[indices[1]] and A[indices[1]] == B[indices[0]]


class Solution:

	def buddyStrings(self, A: str, B: str) -> bool:
		if len(A) != len(B):
			return False
		cand = []
		for i in range(len(A)):
			if A[i] != B[i]:
				cand.append(i)
		if len(cand) > 2:
			return False
		if len(cand) == 1:
			return False
		if len(cand) == 2:
			(i, j) = cand
			if A[i] == B[j] and B[i] == A[j]:
				return True
			else:
				return False
		if len(cand) == 0:
			if len(set(list(A))) < len(A):
				return True
			else:
				return False


class Solution:

	def buddyStrings(self, A: str, B: str) -> bool:
		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 zip(A, B):
				if a != b:
					pairs.append((a, b))
				if len(pairs) > 2:
					return False
			return len(pairs) == 2 and pairs[0] == pairs[1][::-1]


class Solution:

	def buddyStrings(self, A: str, B: str) -> bool:
		if len(A) != len(B):
			return False
		if A == B and len(set(A)) < len(A):
			return True
		diffs = [(a, b) for (a, b) in zip(A, B) if a != b]
		return len(diffs) == 2 and diffs[0] == diffs[1][::-1]


class Solution:

	def buddyStrings(self, A: str, B: str) -> bool:
		if A == B and len(set(A)) < len(B):
			return True
		if len(A) != len(B):
			return False
		diff_A = []
		diff_B = []
		for i in range(len(A)):
			if A[i] != B[i]:
				diff_A.append(A[i])
				diff_B.append(B[i])
		return len(diff_A) == len(diff_B) == 2 and diff_A[::-1] == diff_B


class Solution:

	def buddyStrings(self, A: str, B: str) -> bool:
		count_A = {}
		doubled = False
		for (i, a) in enumerate(A):
			if a not in count_A:
				count_A[a] = set()
			else:
				doubled = True
			count_A[a].add(i)
		off = 0
		for (i, b) in enumerate(B):
			if b not in count_A:
				return False
			elif i in count_A[b]:
				count_A[b].remove(i)
				if not count_A[b]:
					del count_A[b]
			else:
				off += 1
				if off > 2:
					return False
		return doubled or off == 2