这是我参与11月更文挑战的第23天,活动详情查看:2021最后一次更文挑战
亲密字符串
该题出自力扣的859题——亲密字符串(简单题),题解是自己做的
审题
给你两个字符串 s 和 goal ,只要我们可以通过交换 s 中的两个字母得到与 goal 相等的结果,就返回 true ;否则返回 false 。
交换字母的定义是:取两个下标 i 和 j (下标从 0 开始)且满足 i != j ,接着交换 s[i] 和 s[j] 处的字符。
例如,在 "abcd" 中交换下标 0 和下标 2 的元素可以生成 "cbad" 。
-
简单概括就是给定两个字符串,找到其中可以转换的两个字符,存在则返回true,不存在则返回false
-
之所以是简单题,想要实现的方法和思路很多
- 超过两个不相同字符则可以直接返回false
- 如果两个字符串完全相同,则可以直接比较自身字符是否存在相同字符
-
一开始为了通过,野蛮冲撞,直接空间复杂度拉满,HashMap + ArraysList
- 利用hashMap去计算是否有相同的字符
- 利用ArraysList去存储不相同的字符
- 完美击败5%
public boolean buddyStrings(String s, String goal) { int n = s.length(); if (n != goal.length())return false; HashMap<Character,Integer> map = new HashMap<>(); List<Integer> list = new ArrayList<>(); for (int i = 0; i<s.length();i++){ if (s.charAt(i) != goal.charAt(i)){ list.add(i); } map.put(s.charAt(i),map.getOrDefault(s.charAt(i),0)+1); } if (list.size() == 2){ if ((s.charAt(list.get(0)) == goal.charAt(list.get(1))) && (s.charAt(list.get(1)) == goal.charAt(list.get(0))))return true; } if (list.size() == 0){ for (Integer value: map.values()) { if (value>1)return true; } } return false; } -
优化后,利用数组下标映射,用局部变量去定义是否相同值取代HashMap
编码
public static boolean buddyStrings(String s, String goal) {
int n = s.length();
if (n != goal.length())return false;
int differentNum = 0,diffFirst = -1,diffSecond = -1;
boolean sameChar = false;
boolean[] map = new boolean[26];
for (int i = 0; i<s.length();i++){
if (s.charAt(i) != goal.charAt(i)){
differentNum++;
if (diffFirst == -1){
diffFirst = i;
}else {
diffSecond = i;
}
}
if (differentNum>2)return false;
sameChar |= map[s.charAt(i) - 'a'];
map[s.charAt(i) - 'a'] = true;
}
if (differentNum == 2){
if ((s.charAt(diffFirst) == goal.charAt(diffSecond)) &&
(s.charAt(diffSecond) == goal.charAt(diffFirst)))return true;
}
return sameChar && differentNum == 0;
}