题目描述
给你两个字符串 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 相等。 示例 4:
输入:s = "aaaaaaabc", goal = "aaaaaaacb" 输出:true
提示:
1 <= s.length, goal.length <= 2 * 104 s 和 goal 由小写英文字母组成
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/bu… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解思路
- s和goal长度不等,则无论如何交换s也不可能相等。
- s和goal如果完全一样,如果s或goal存在相同的字符,则只要交换相同的字符,交换后的值仍然相等,如果不存在相同字符,则无论交换任何两个字符的位置都会导致s与goal不相等。
- 排除以上两种可能后,我们只需要找到两处s和goal的不同之处,然后比较s的两处不同字符交换后是否与goal的字符相等即可,如果在循环过程中存在大于两处的不同,则可提前结束循环,因为多余两处不同的字符串无论如何交换两处,都不可能使得s和goal相等
题解代码
* @lc app=leetcode.cn id=859 lang=javascript
*
* [859] 亲密字符串
*/
// @lc code=start
/**
* @param {string} s
* @param {string} goal
* @return {boolean}
*/
var buddyStrings = function(s, goal) {
//长度不等则无论怎么交换都不会相等
if(s.length !== goal.length) return false;
//字符串相等,如果存在两个字符相等的情况则交换后仍然相等
//Set函数是对字符串去重,如果去重后s和goal长度不等说明s和goal中存在相同字符
//交换相同字符值仍然相等
if(s === goal) return s.length > new Set(goal).size;
let dif = 0;
let difStr1=difStr2="";
for (let i = 0; i < s.length; i++) {
if(s[i] !== goal[i]){
dif++;
if(dif > 2) return false;//超过两处不同必不可能交换两处后相等
difStr1 = s[i] + difStr1;//goal中与s不同的两个字符颠倒后的
difStr2 = difStr2 + goal[i];//goal中与s不同的两个字符
}
}
return difStr1 === difStr2? true : false;
};
// @lc code=end