题目
859. 亲密字符串
给你两个字符串 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 相等。
思路:
暴力解法,遍历整个字符串,把每两个字母交换位置,然后和goal比较。
/**
* @param {string} s
* @param {string} goal
* @return {boolean}
*/
var buddyStrings = function(s, goal) {
let arr = s.split('');
for(let i=0;i<arr.length;i++){
for(let j=i+1;j<arr.length;j++){
[arr[i],arr[j]] = [arr[j],arr[i]]
if(arr.join('') == goal){
return true;
}else{
[arr[i],arr[j]] = [arr[j],arr[i]]
}
}
}
return false;
};
超时间限制, 那我们就改进方案:
两个字符字符串交换两个字符串后相当,只有以下两种情况:
- 两个字符串相等,且字符串内有重复字段。
- 字符串只有两个字符不一样,且s[i] == goal[j],s[j] == goal[i].
所以思路变换一下,
- 判断长度不等,直接return false
- 字符串一样,去重后长度小于原来长度,则说明有重复字段,则return true,否则return false
- 遍历字符串,找到不一样的元素的下标并记录下来
- 如果不一样的元素个数不为2,return false
- 如果个数为2,判断s[i] == goal[j] && s[j] == goal[i],return结果
/**
* @param {string} s
* @param {string} goal
* @return {boolean}
*/
var buddyStrings = function(s, goal) {
if(s.length != goal.length) return false;
let arr_s = s.split('');
let arr_goal = goal.split('');
let diffIndex=[];
let count = 0;
if(s === goal){
if(unique(arr_s).length<arr_s.length){
return true;
}else{
return false;
}
}
for(let i=0;i<arr_s.length;i++){
if(arr_s[i] != arr_goal[i]){
diffIndex.push(i);
count++;
}
}
if(count ==2){
return arr_s[diffIndex[0]] == arr_goal[diffIndex[1]] && arr_s[diffIndex[1]] == arr_goal[diffIndex[0]]
}else{
return false;
}
};
function unique(arr){
return Array.from(new Set(arr))
}
这题令我惊讶的是,我以为看了题解会发现什么未知领域的知识,或者惊天大秘密,实际大家的写法虽然千奇百怪,但竟然都不怎么优雅。。。。