携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,点击查看活动详情
一、题目描述:
给你两个字符串 s 和 goal ,只要我们可以通过交换 s 中的两个字母得到与 goal 相等的结果,就返回 true ;否则返回 false 。
交换字母的定义是:取两个下标 i 和 j (下标从 0 开始)且满足 i != j ,接着交换 s[i] 和 s[j] 处的字符。
- 例如,在
"abcd"中交换下标0和下标2的元素可以生成"cbad"。
示例 1:
输入:s = "ab", goal = "ba"
输出:true
解释:你可以交换 s[0] = 'a' 和 s[1] = 'b' 生成 "ba",此时 s 和 goal 相等。
示例 2:
输入:s = "ab", goal = "ab"
输出:false
解释:你只能交换 s[0] = 'a' 和 s[1] = 'b' 生成 "ba",此时 s 和 goal 不相等。
示例 3:
输入:s = "aa", goal = "aa"
输出:true
解释:你可以交换 s[0] = 'a' 和 s[1] = 'a' 生成 "aa",此时 s 和 goal 相等。
提示:
- 1 <= s.length, goal.length <= 2 * 10^4
- s 和 goal 由小写英文字母组成
二、思路分析:
- 如果字符串A的长度不等于字符串B的长度、字符串A等于字符串B等于空字符串以及字符串A的长度等于字符串B的长度等于1,返回false。
- 相对位置进行比较,并用HashMap记录字符串A每个元素的个数。若相对位置元素不一样count++,若count大于2,返回false。
- 如果count等于0,代表字符串A和字符串B完全相等,这时候判断字符串A中是否有元素个数大于2,若有返回true。
- 如果count等于1,返回false。
- 如果count等于2,比较(A.charAt(i) == B.charAt(j)) && (A.charAt(j) == B.charAt(i)),若为true,返回true,反之返回false。
三、AC 代码:
public class Solution {
public boolean buddyStrings(String A, String B) {
if (A.length() != B.length() || (A.equals("") && B.equals("")) || (A.length()==1 && B.length() == 1)) {
return false;
}
HashMap<Character,Integer> map = new HashMap<>();
List<Integer> list = new ArrayList<>();
int count = 0;
for (int i=0; i<A.length(); i++) {
if (map.containsKey(A.charAt(i))) {
map.put(A.charAt(i),map.get(A.charAt(i)) + 1);
} else {
map.put(A.charAt(i),1);
}
if (A.charAt(i) != B.charAt(i)) {
count++;
list.add(i);
if (count > 2) {
return false;
}
}
}
if (count == 0) {
if (A.equals(B)) {
Object[] lists = map.values().toArray();
for (int i=0; i<lists.length; i++) {
if ((Integer)lists[i] >= 2) {
return true;
}
}
}
}
if (count == 1) {
return false;
}
if (count == 2) {
if (A.charAt(list.get(0)) == B.charAt(list.get(1)) && A.charAt(list.get(1)) == B.charAt(list.get(0))) {
return true;
}
}
return false;
}
}