算法小练习之求相似度为K的字符串

262 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情

1、前言

每天一个算法小练习,本篇使用Java实现。

2、题目描述

字符串 s1 和 s2 是 k 相似的(对于某些非负整数 k ),如果我们可以交换 s1 中两个字母的位置正好 k 次,使结果字符串等于 s2 。给定两个字符串 s1 和 s2 ,返回 s1 和 s2 与 k 相似的最小 k 。

提示:

  • 1 <= s1.length <= 20
  • s2.length == s1.length
  • s1 和 s2  只包含集合 {'a', 'b', 'c', 'd', 'e', 'f'} 中的小写字母

2.1、示例1

输入:s1 = "ab", s2 = "ba"

输出:1

2.2、示例2

输入:s1 = "abc", s2 = "bca"

输出:2

3、解题思路

广度优先搜索实现,在每一次循环处理时,从源字符串中寻找目标串的当前字符,找到后则替换。为了不超时,我们需要进一步改进:

  • 1、判断两个字符串相同位置的字符是否相同,是则移除该字符不予考虑,减少计算量;
  • 2、用于交换的源字符串在每次迭代时长度会减少1,不需要挨个元素交换

3.1、实现代码

 public int kSimilarity(String str1, String str2) {
    Queue<String> queue = new ArrayDeque<>();
    queue.offer(str1);
    int step = 0;
    while (!queue.isEmpty()) {
        //每次迭代的size次中输出的全是父结点
        int size = queue.size();
        while (size-- > 0) {
            String currStr = queue.poll();
            if (currStr.equals(str2)) {
                //若队首cur与目标相同,则返回step
                return step;
            }
            // 接近目标的结果
            int firstIdx = 0;
            // 忽略相同元素(匹配区间)找到str2与str1的第一个不相同元素str2x
            for(; firstIdx < currStr.length(); ++ firstIdx) {
                if (currStr.charAt(firstIdx) != str2.charAt(firstIdx)) {
                    break;
                }
            }
            // 找到str1的不匹配区间中与str2x相同的元素str1x
            for (int secondIdx = firstIdx + 1; secondIdx < currStr.length(); ++secondIdx) {
                if (currStr.charAt(secondIdx) == str2.charAt(firstIdx)) {
                    char[] tmp = currStr.toCharArray();
                    swap(tmp, firstIdx, secondIdx);
                    // 把str1的str1x和str2x下标互换后放入队列中
                    queue.offer(new String(tmp));
                    swap(tmp, firstIdx, secondIdx);
                }
            }
        }
        // 每层结束后step+1
        step++;
    }
    return step;
}

/**
    * 交换下标
    * @param temp
    * @param i
    * @param j
    */
void swap(char[] temp, int i, int j) {
    char tmp = temp[i];
    temp[i] = temp[j];
    temp[j] = tmp;
}

3.2、执行结果

image.png

好了、本期就先介绍到这里,有什么需要交流的,大家可以随时私信我。😊