3138.同位字符串连接的最小长度

目标

给你一个字符串 s ,它由某个字符串 t 和若干 t 的 同位字符串 连接而成。

请你返回字符串 t 的 最小 可能长度。

同位字符串 指的是重新排列一个单词得到的另外一个字符串,原来字符串中的每个字符在新字符串中都恰好只使用一次。

示例 1:

输入:s = "abba"
输出:2
解释:
一个可能的字符串 t 为 "ba" 。

示例 2:

输入:s = "cdef"
输出:4
解释:
一个可能的字符串 t 为 "cdef" ,注意 t 可能等于 s 。

说明:

  • 1 <= s.length <= 10^5
  • s 只包含小写英文字母。

思路

字符串 s 由某个字符串 t 以及若干(可以为0) t 的同位字符串 连接 而成,返回字符串 t 最小的可能长度。同位字符串指构成字符串的字符分布完全相同,换句话说就是不同字符的种类与数量完全相同。

特别注意该题与字串的顺序有关,比如 aabb 并不能由 ab 拼接而来,它的同位字符串是 abba,只能构成 abba abab baab baba

注意到子串的长度 length 一定能够被 s.length 整除。将字符串截成 k 个长度为 length 的子字符串,通过计算这些子字符串的字母个数,判断是否是同位字符串,从小到大遍历因数 length,取最小的即可。

代码


/**
 * @date 2024-12-20 9:08
 */
public class MinAnagramLength3138 {

    public int minAnagramLength_v1(String s) {
        int n = s.length();
        int[] cnt = new int[26];
        Map<Integer, int[]> possibleLength = new LinkedHashMap<>();
        for (int i = 0; i < n; i++) {
            int c = s.charAt(i) - 'a';
            cnt[c]++;
            int length = i + 1;
            if (n % length == 0) {
                int[] composition = new int[26];
                System.arraycopy(cnt, 0, composition, 0, 26);
                possibleLength.put(length, composition);
            }
        }
        char[] chars = s.toCharArray();
        for (Map.Entry<Integer, int[]> entry : possibleLength.entrySet()) {
            int length = entry.getKey();
            if (length == n) {
                return n;
            }
            int[] composition = entry.getValue();
            int loop = n / length;
            boolean find = true;
            here:
            for (int i = 0; i < loop; i++) {
                int[] tmp = new int[26];
                System.arraycopy(composition, 0, tmp, 0, 26);
                for (int j = 0; j < length; j++) {
                    int c = chars[i * length + j] - 'a';
                    tmp[c]--;
                    if (tmp[c] < 0) {
                        find = false;
                        break here;
                    }
                }
            }
            if (find) {
                return length;
            }
        }
        return n;
    }

}

性能

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注