0
点赞
收藏
分享

微信扫一扫

leet code 854. 相似度为 K 的字符串

Go_Viola 2023-09-14 阅读 35

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;
    }

}

举报

相关推荐

0 条评论