目录
题目
给你长度相等的两个字符串 s1
和 s2
。一次字符串交换 操作的步骤如下:选出某个字符串中的两个下标(不必不同),并交换这两个下标所对应的字符。
如果对其中一个字符串执行最多一次字符串交换就可以使两个字符串相等,返回 true
;否则,返回 false
。
oj链接
1790. 仅执行一次字符串交换能否使两个字符串相等 - 力扣(Leetcode)
方法--计数法
思路
- 遍历数组,利用count记录有几个位置元素不一样,当只有两个位置元素不一样时(即count == 2),才有可能通过一次交换使得两个数组相等。
- 利用tmp1和tmp2分别记录第一次元素不一样的下标和第一次元素不一样的下标。如果count == 2时,那么就对其中一个字符串进行交换,交换完后依旧要判断是否两个字符串是否相等。(这里依旧要判断是否相等的原因是有可能交换完后依旧不相等)
- 继续遍历数组,直到跳出循环,遍历结束,就可以判断是否可以通过一次交换完成了。分为三种情况:
- count == 0 所有元素都相等,无需交换,直接返回true
- count == 2 只有两个位置元素不相等,且交换后相等(不相等的情况依旧在上面排除掉了),返回true
- count != 2 && count != 0 1个元素不相等或者超过两个元素不相等,返回false
代码实现
private String swap(String s,int pos1,int pos2) {
char[] ch = s.toCharArray();
char ret = ch[pos1];
ch[pos1] = ch[pos2];
ch[pos2] = ret;
s = String.valueOf(ch);
return s;
}
public boolean areAlmostEqual(String s1, String s2) {
Solution soulution = new Solution();
int count = 0;
int tmp1 = 0;
int tmp2 = 0;
for(int i =0;i < s1.length();i++) {
if(s1.charAt(i) != s2.charAt(i)) {
count++;
if(count == 1) {
tmp1 = i;//记录第一次不一样的元素的位置
}
if(count == 2) {
tmp2 = i;//记录第二次不一样的元素的位置
s1 = soulution.swap(s1,tmp1,tmp2);//交换
//判断交换后是否相等
if(s1.charAt(tmp1) != s2.charAt(tmp1)||
s1.charAt(tmp2) != s2.charAt(tmp2)) {
return false;
}
}
if(count > 2) {
break;
}
}
}
if(count == 0) {
return true;
}
if(count == 2) {
return true;
}
return false;
}
总结
在解这道题目时,虽然思路简单,但是在代码实现过程中还是犯了不少的错误,下面总结一下在代码实现时我踩过的坑。
坑一
在一开始时,以为只要两个字符串中有两个位置的元素不一样那么就可以通过一次交换完成,没有考虑这两个位置的元素交换之后是否还相等。
坑二
在代码实现过程中,没有注意代码的实现逻辑,在判断有几个元素不相等时,绿框的内容应该是建立在元素不相等的情况下判断的。
坑三
字符数组转换为字符串应该使用字符串的valueOf()方法,而不应该使用字符数组的toString()方法。
数组没有重写Object父类的toString()方法,所以返回值是数组的引用地址。
字符串的valueOf()方法,返回一个新建的字符串对象。