854.相似度为 K 的字符串
show code
- 解析+代码
import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
/**
* desc :
* <p>
* create time : 2023/9/8 20:04
*/
public class L_854 {
public int kSimilarity(String s1, String s2) {
// 首先明确:需要交换的是 字符串 s1 中两个字母的位置.
// 交换多少次 s1 才能和 s2 相等.
// 求 最小的交换次数——即,最小相似度,,,求最小的相似度.
// 根据示例:s1 = "ab" , s2 = "ba" s1 中的字符,交换一次即可和 s2 相同。所以输出 1
// 如何解?
// 首先可以确定字符 s1 和 s2 的长度相同
/* 首先可以 从第一个字符进行遍历
* ————判断 s1 和 s2 的第一个字符是否相同
* ————如果相同的话:跳过
* ————不相同的话:那么开始向后遍历,去找到可以交换的字符,使交换过后当前位置字符相同
* ————符合交换条件的字符可能有多个,有几个交换几次,然后得到一组交换过的字符
* ————此时记录交换次数
* ————然后判断交换过后的字符是否和 s2 相等,如果相等,则找到了最小相似度.直接输出
*
* ————那么可以用一个栈来记录当前需要进行交换的字符.
*/
int n = s1.length();
Deque<Word> queue = new LinkedList<>();
// 初始化字符串 s1
Word word = new Word(0, s1);
queue.offer(word);
Set<String> dul = new HashSet<>();
dul.add(s1);
// 记录交换次数
int cnt = 0;
while (!queue.isEmpty()) {
int sz = queue.size();
for (int i = 0; i < sz; i++) {
Word word1 = queue.poll();
int localIdx = word1.index;
// 当前字符串.
String s = word1.word;
if(s.equals(s2)) {
// 如果相等了,那么直接跳出循环,并且输出.
return cnt;
}
// 这里少了一个步骤,需要查找 从 localIdx 开始第一个 不想等的字符
while(localIdx < n && s.charAt(localIdx) == s2.charAt(localIdx)) {
localIdx++;
}
// 这个时候 newIdx 位置不相同.
// 证明不相等,从 当前位置 localIdx 位置开始向后寻找 满足交换条件的字符.
// 从 startIdx 位置开始遍历字符 s1, 去找和 at 字符相等的字符.
for (int j = localIdx + 1; j < n; j++) {
if(s.charAt(j) == s2.charAt(j)) {
continue;
}
if(s.charAt(j) == s2.charAt(localIdx)) {
// 满足交换条件了.
String newWord = swap(s, localIdx, j);
if(!dul.contains(newWord)) {
// 没有出现过 newWord
queue.offer(new Word(localIdx + 1, newWord));
dul.add(newWord);
}
}
}
}
cnt++;
}
return cnt;
}
private String swap(String s, int localIdx, int startIdx) {
char[] chars = s.toCharArray();
char temp = chars[localIdx];
chars[localIdx] = chars[startIdx];
chars[startIdx] = temp;
return String.valueOf(chars);
}
public static void main(String[] args) {
L_854 l = new L_854();
//int i = l.kSimilarity("ab", "ba");
//int i = l.kSimilarity("abac", "baca");
//int i = l.kSimilarity("aabc", "abca");
//int i = l.kSimilarity("abac", "baca");
int i = l.kSimilarity("baababbaaabbabaaabaa", "abaabaabababaabababa");
System.out.println("the result is : " + i);
}
}
class Word {
public int index;
public String word;
public Word(int index, String word) {
this.index = index;
this.word = word;
}
}