K-Similar Strings
题目来源:LeetCode No.854
题目描述:
K-similar
字符串的定义:对于任意两个字符串A
和B
,若对其中一个字符串中的字符交换了K
次后(K>=0)
,使得A
与B
完全相等,则称A
和B
为K-similar
字符串。
现给定两个字谜A
和B
为K-similar
字符串,返回最小的K
。
例1:
输入: A = "ab",B = "ba"
输出:1
例2:
输入: A = "abc",B = "bca"
输出: 2
例3:
输入: A = "abac",B = "baca"
输出: 2
例4:
输入: A = "aabc",B = "abca"
输出: 2
注意:
1. 1 <= A.length == B.length <= 20
2. A
并B
只包含来自集合{'a', 'b', 'c', 'd', 'e', 'f'}
的小写字母
思路分析:
为防止堆栈溢出,选择使用BFS算法:先将字符串转换为数组,从第一个字符开始往后搜索,每个字符的匹配为一层,当出现分支时压栈保存,当匹配到最后一个字符时,选取最小的交换次数即为解。
代码示例:
/**
* @param {string} A
* @param {string} B
* @return {number}
*/
var kSimilarity = function(A, B) {
if (A === B) { return 0; }
var a = A.split(""); // 将A转换为数组
var b = B.split(""); // 将B转换为数组
var stack = [[b,0,0]]; // 用于存放 [当前状态的数组,下一次开始交换的索引,当前已交换的次数] 的堆栈
var len = a.length;
var res = len; // 最不理想的状态下(没个字符都需要交换)K值为len
while (stack.length) { // BFS
var node = stack.pop();
var arr = node[0];
var index = node[1];
var count = node[2];
for (var i = index ; i < len; i++) {
if(arr[i] !== a[i]) {
var choice = findStr(a,arr,a[i],i);
while (choice.length) {
var newArr = exchange(arr.slice(0),i,choice.pop());
stack.push([newArr,i+1,count+1]);
}
break;
}
}
if (i == len && count < res) { // 选择最小的K值
res = count;
}
}
return res;
};
// 用于交换数组内指定索引的值
function exchange(arr,m,n) {
var tmp = arr[m];
arr[m] = arr[n];
arr[n] = tmp;
return arr;
}
// 用于寻找可以交换的的字符的索引
function findStr(arr1,arr2,s,index) {
var len = arr2.length;
var choice = [];
for (var i = index; i < len; i++) {
if (arr2[i] == s && arr1[i]!=s) {
choice.push(i);
}
}
return choice;
}