持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情
刷题的日常-2022年10月11号
一天一题,保持脑子清爽
仅执行一次字符串交换能否使两个字符串相等
来自leetcode的 1790 题,题意如下:
给你长度相等的两个字符串 s1 和 s2 。一次 字符串交换 操作的步骤如下:选出某个字符串中的两个下标(不必不同),并交换这两个下标所对应的字符。
如果对 其中一个字符串 执行 最多一次字符串交换 就可以使两个字符串相等,返回 true ;否则,返回 false 。
示例1:
输入: s1 = "bank", s2 = "kanb"
输出: true
解释: 例如,交换 s2 中的第一个和最后一个字符可以得到 "bank"
示例2:
输入: s1 = "attack", s2 = "defend"
输出: false
解释: 一次字符串交换无法使两个字符串相等
理解题意
通过题意,我们可以将信息整理如下:
- 题目给出两个字符串
- 要求我们判断是否能进行一次转换使两个字符串相等
- 需要注意的是,没有转换的时候也是满足题意的,也应该返回true
做题思路
从题目可以看出,如果最多交换一次的话,那么至多只有两个字符的位置不匹配,或者是全部匹配的情况,我们可以将过程整理如下:
- 用两个指针记录差异索引的位置
- 循环两个字符串
- 如果字符相等,继续
- 如果不相等,则将差异的位置记录到指针当中
- 如果超过两个位置不一致,则返回false
- 最后判断下只有一个字符有差异,返回false
- 然后判断交换之后字符是否匹配
代码实现
代码实现如下:
public class Solution {
public boolean areAlmostEqual(String s1, String s2) {
List<Integer> idx = new ArrayList<>(2);
char c1, c2;
for (int i = 0; i < s1.length(); i++) {
c1 = s1.charAt(i);
c2 = s2.charAt(i);
if (c1 == c2) {
continue;
}
idx.add(i);
if (idx.size() > 2) {
return false;
}
}
if (idx.size() < 2) {
return idx.size() == 0;
}
return s1.charAt(idx.get(0)) == s2.charAt(idx.get(1)) && s1.charAt(idx.get(1)) == s2.charAt(idx.get(0));
}
}