方法一 个人方法:
- 首先s和goal要是长度不一样或者就只有一个字符这两种情况可以直接排除
- 剩下的情况s和goal的长度都是一样的,s的长度为2也是特殊情况,只有s的第一位等于goal的第二位,s的第二位等于goal的第一位才能满足
- 剩下的我们需要统计s的goal的哪几位字符是不一样的,并用数组保存不同的位置
- 如果不同的位数等于1那么无论怎么交换都不能满足,不同的位数大于2那么只交换一次也不能满足
- 如果没有不同的字符,说明s和goal是一样的字符串,这种情况只需要s或者goal有任意一个字符出现了两次及以上,把相同的字符互相调换,它还是原来的字符串
var buddyStrings = function(s, goal) {if(s.length!=goal.length || s.length<=1){return false}if(s.length==2){if(s[0]===goal[1] && s[1]===goal[0]) return trueelse return false }var diff=[]for(var i=0;i<s.length;i++){if(s[i]!=goal[i]){diff.push(i)}}if(diff.length===2){if(s[diff[0]]===goal[diff[1]] && s[diff[1]]==goal[diff[0]]) return trueelse return false}else if(diff.length===1 || diff.length>2) return falseelse{var set = new Set(s)return s.length===set.size?false:true}
};
消耗时间和内存情况:
方法二 官方解法:
思路差不太多,我把情况分的太细了啰嗦了一点,官方解法思路更加直接精确
设i和j为需要交换的字符的位置,如果满足交换 s[i] 和 s[j]后两个字符串相等,那么需要满足以下几个条件使得 s 和 goal为亲密字符串:
- 字符串 sss 的长度与字符串 goal\textit{goal}goal 的长度相等;
-
存在 i≠j 且满足 s[i]=goal[j]以及 s[j]=goal[i],实际在 s[i],s[j],goal[i],goal[j]这四个自由变量中,只存在两种情况:
-
满足 s[i]=s[j]:则此时必然满足 s[i]=s[j]=goal[i]=goal[j],字符串 s 与 goal相等,我们应当能够在 s中找到两个不同的索引 i,j,且满足 s[i]=s[j],如果能够找到两个索引不同但值相等的字符则满足 s与 goal 为亲密字符串;否则不为亲密字符串。
-
满足 s[i]≠s[j]:满足 s[i]=goal[j],s[j]=goal[i],s[i]≠s[j]的情况下,两个字符串 s 与 goal除了索引 i,j 以外的字符都是匹配的。
var buddyStrings = function(s, goal) {if (s.length != goal.length) {return false;}if (s === goal) {const count = new Array(26).fill(0);for (let i = 0; i < s.length; i++) {count[s[i].charCodeAt() - 'a'.charCodeAt()]++;if (count[s[i].charCodeAt() - 'a'.charCodeAt()] > 1) {return true;}}return false;} else {let first = -1, second = -1;for (let i = 0; i < s.length; i++) {if (s[i] !== goal[i]) {if (first === -1)first = i;else if (second === -1)second = i;elsereturn false;}}return (second !== -1 && s[first] === goal[second] && s[second] === goal[first]);}
};作者:力扣官方题解
来源:力扣(LeetCode)
消耗时间和内存情况: