Leetcode 854. 相似度为 K 的字符串
题目
如果可以通过将 A 中的两个小写字母精确地交换位置 K 次得到与 B 相等的字符串,我们称字符串 A 和 B 的相似度为 K(K 为非负整数)。
给定两个字母异位词 A 和 B ,返回 A 和 B 的相似度 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 <= A.length == B.length <= 20
- A 和 B 只包含集合 {‘a’, ‘b’, ‘c’, ‘d’,‘e’, ‘f’} 中的小写字母。
题解
bfs+贪心
我们进行搜索的过程中,应该尽可能的保证我们移动的元素不能为对应相等的元素,且移动后至少要有1个元素对应相等,若能保证两个元素都对应相等,则不需要探索其他情况。
详细过程见代码
代码
int kSimilarity(string A, string B) {
unordered_set<string> visit;
int len = A.length(),size;
queue<string> q;
q.push(A);
visit.insert(A);
int ans = -1;
bool valid;
vector<string> next;
while(!q.empty()){
size = q.size();
ans++;
while(size--){
string now = q.front();
if(now == B) return ans;
q.pop();
valid = false;
next.clear();
for(int i=0; i<len && !valid; i++){
if(now[i]==B[i]) continue; //本来就相等,我们不移动
for(int j=i+1; j<len; j++){
if(now[j]==B[j]) continue; //本来就相等,我们不移动
if(now[i]!=B[j]) continue; //我们要保证移动后有一个元素会与之对应。也就是B[j]会对应
swap(now[i],now[j]);
if(visit.find(now) == visit.end()){
visit.insert(now);
if(now[i]==B[i]){ //交换后我们能保证now[j]==B[j];如果两个元素都对应了, 也就是又满足了now[i]==B[i]。则就是最好的交换,不必继续探索
valid = true;
next.clear();
q.push(now);
break;
}else next.push_back(now);
}
swap(now[j],now[i]);
}
}
for(auto str : next)
q.push(str);
}
};
return -1;
}
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/k-similar-strings
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。