目标
给你两个字符串 s1 和 s2 ,两个字符串的长度都为 4 ,且只包含 小写 英文字母。
你可以对两个字符串中的 任意一个 执行以下操作 任意 次:
- 选择两个下标 i 和 j 且满足 j - i = 2 ,然后 交换 这个字符串中两个下标对应的字符。
如果你可以让字符串 s1 和 s2 相等,那么返回 true ,否则返回 false 。
示例 1:
输入:s1 = "abcd", s2 = "cdab"
输出:true
解释: 我们可以对 s1 执行以下操作:
- 选择下标 i = 0 ,j = 2 ,得到字符串 s1 = "cbad" 。
- 选择下标 i = 1 ,j = 3 ,得到字符串 s1 = "cdab" = s2 。
示例 2:
输入:s1 = "abcd", s2 = "dacb"
输出:false
解释:无法让两个字符串相等。
说明:
- s1.length == s2.length == 4
- s1 和 s2 只包含小写英文字母。
思路
有两个长度为 4 的字符串 s1 和 s2,判断能否通过操作使二者相等,每次操作可将第一个与第三个 或者 第二个与第四个 字母交换。
实际上就是判断 s1[0]s1[2] 与 s2[0]s2[2] 或者 s2[2]s2[0] ,以及 s1[1]s1[3] 与 s2[1]s2[3] 或者 s2[3]s2[1] 是否相等。
为了避免复杂判断,直接根据奇偶性分组,s1 中的字母 +1,s2 中的字母 -1,最后判断字母出现次数是否为 0 即可。
代码
/**
* @date 2026-03-29 16:28
*/
public class CanBeEqual2839 {
public boolean canBeEqual(String s1, String s2) {
char[] chars1 = s1.toCharArray();
char[] chars2 = s2.toCharArray();
Map<Character, Integer>[] map = new HashMap[2];
Arrays.setAll(map, x -> new HashMap<>());
for (int i = 0; i < 4; i++) {
int rem = i % 2;
map[rem].merge(chars1[i], 1, Integer::sum);
map[rem].merge(chars2[i], -1, Integer::sum);
}
for (int i = 0; i < 2; i++) {
for (Integer value : map[i].values()) {
if (value != 0) {
return false;
}
}
}
return true;
}
}
性能
