2531. Make Number of Distinct Characters Equal

题目 #

You are given two 0-indexed strings word1 and word2.

A move consists of choosing two indices i and j such that 0 <= i < word1.length and 0 <= j < word2.length and swapping word1[i] with word2[j].

Return true if it is possible to get the number of distinct characters in word1 and word2 to be equal with exactly one move. Return false otherwise.

Example 1:

Input: word1 = "ac", word2 = "b"
Output: false
Explanation: Any pair of swaps would yield two distinct characters in the first string, and one in the second string.

Example 2:

Input: word1 = "abcc", word2 = "aab"
Output: true
Explanation: We swap index 2 of the first string with index 0 of the second string. The resulting strings are word1 = "abac" and word2 = "cab", which both have 3 distinct characters.

Example 3:

Input: word1 = "abcde", word2 = "fghij"
Output: true
Explanation: Both resulting strings will have 5 distinct characters, regardless of which indices we swap.

Constraints:

  • $1 <= word1.length, word2.length <= 10^5$
  • word1 and word2 consist of only lowercase English letters.

思路1 统计加各种情况枚举 #

分析 #

  • 自己想得,其实想复杂了,具体看注释吧

代码 #

  1func abs(a int) int {
  2	if a < 0 {
  3		return -a
  4	}
  5	return a
  6}
  7
  8func isItPossible(word1 string, word2 string) bool {
  9	set1 := make(map[byte]int)
 10	set2 := make(map[byte]int)
 11	for _, t := range word1 {
 12		v := byte(t)
 13		if set1[v] > 0 {
 14			set1[v]++
 15		} else {
 16			set1[v] = 1
 17		}
 18	}
 19	for _, t := range word2 {
 20		v := byte(t)
 21		if set2[v] > 0 {
 22			set2[v]++
 23		} else {
 24			set2[v] = 1
 25		}
 26	}
 27
 28	// 两个字符串中不同字符个数相等直接返回成功
 29	diff := abs(len(set1) - len(set2))
 30	more, less := set1, set2
 31	if len(set1) < len(set2) {
 32		more, less = set2, set1
 33	}
 34	if diff == 0 {
 35		// 多不变少不变,多的和少的有相同的
 36		//			    多的和少的各有一个只有一个但对方没有的
 37		// 多加少加		多的和少的各有一个有两个的
 38		for k := range more {
 39			if less[k] > 0 {
 40				return true
 41			}
 42			if more[k] >= 2 {
 43				for k1 := range less {
 44					if less[k1] >= 2 {
 45						return true
 46					}
 47				}
 48			} else if more[k] == 1 && less[k] == 0 {
 49				for k1 := range less {
 50					if less[k1] == 1 && more[k1] == 0 {
 51						return true
 52					}
 53				}
 54			}
 55		}
 56		return false
 57	}
 58	if diff == 1 {
 59		// 多减少不变,多的要替换的只有1个的并且替换来的是替换后已经有的
 60		//			  少的要替换的是有2个的并且替换来的是已经有的
 61		// 多减少动了一下还是没变,多的要替换的只有1个的并且替换来的是替换后已经有的
 62		//						 少的要替换的是有1个的并且替换来的是少的没有的
 63		// 多不变少加,多的要替换的是有2个的并且替换来的是已经有的
 64		// 			  少的要替换的是有2个的并且替换来的是没有的
 65		// 多变了一下但还是没变少加,多的要替换的是只有1个的并且是少的没有的,少的替换过来的是有两个的也是多的没有的
 66		for k := range less {
 67			if less[k] >= 2 && more[k] > 0 {
 68				for k1 := range more {
 69					if more[k1] == 1 && less[k1] > 0 && k1 != k {
 70						return true
 71					}
 72					if more[k1] >= 2 && less[k1] == 0 {
 73						return true
 74					}
 75				}
 76			}
 77			if less[k] >= 2 && more[k] == 0 {
 78				for k1 := range more {
 79					if more[k1] == 1 && less[k1] == 0 {
 80						return true
 81					}
 82				}
 83			}
 84			if less[k] == 1 && more[k] > 0 {
 85				for k1 := range more {
 86					if k != k1 && more[k1] == 1 && less[k1] == 0 {
 87						return true
 88					}
 89				}
 90			}
 91		}
 92		return false
 93	}
 94	if diff == 2 {
 95		// 多减少加,多的要替换的是只有1个的并且替换来的是替换后已经有的
 96		// 			少的要替换的是有2个的并且替换来的是没有的
 97		for k := range more {
 98			if more[k] == 1 && less[k] == 0 {
 99				for k1 := range less {
100					if less[k1] >= 2 && more[k1] > 0 && k1 != k {
101						return true
102					}
103				}
104			}
105		}
106		return false
107	}
108	return false
109}

思路2 和上面思路一样,只不过换了遍历方式 #

分析 #

  • 第一步统计少不了
  • 第二步判断是否不可行也少不了
  • 第三步遍历所有的交换可能,有一种满足就返回

代码 #

 1func isItPossible1(word1 string, word2 string) bool {
 2	set1 := make(map[rune]int)
 3	set2 := make(map[rune]int)
 4	for _, t := range word1 {
 5		set1[t]++
 6	}
 7	for _, t := range word2 {
 8		set2[t]++
 9	}
10
11	diff := len(set1) - len(set2)
12	if diff > 2 || diff < -2 {
13		return false
14	}
15
16	getInt := func(x bool) int {
17		if x {
18			return 1
19		}
20		return 0
21	}
22
23	for k1, c1 := range set1 {
24		for k2, c2 := range set2 {
25			if k1 == k2 {
26				// 相等,交换不改变,那么长度差为0就可以
27				if diff == 0 {
28					return true
29				}
30			} else {
31				// 不相等,交换会变化,变化后相等即可
32				// 当前长度 - k1是否唯一 + k2是否存在
33				if (len(set1) - getInt(c1 == 1) + getInt(set1[k2] == 0)) == (len(set2) - getInt(c2 == 1) + getInt(set2[k1] == 0)) {
34					return true
35				}
36			}
37		}
38	}
39	return false
40}