leetcode
leetcode 2751 ~ 2800
数组中的最短非公共子字符串

数组中的最短非公共子字符串

难度:

标签:

题目描述

You are given an array arr of size n consisting of non-empty strings.

Find a string array answer of size n such that:

  • answer[i] is the shortest substring of arr[i] that does not occur as a substring in any other string in arr. If multiple such substrings exist, answer[i] should be the lexicographically smallest. And if no such substring exists, answer[i] should be an empty string.

Return the array answer.

 

Example 1:

Input: arr = ["cab","ad","bad","c"]
Output: ["ab","","ba",""]
Explanation: We have the following:
- For the string "cab", the shortest substring that does not occur in any other string is either "ca" or "ab", we choose the lexicographically smaller substring, which is "ab".
- For the string "ad", there is no substring that does not occur in any other string.
- For the string "bad", the shortest substring that does not occur in any other string is "ba".
- For the string "c", there is no substring that does not occur in any other string.

Example 2:

Input: arr = ["abc","bcd","abcd"]
Output: ["","","abcd"]
Explanation: We have the following:
- For the string "abc", there is no substring that does not occur in any other string.
- For the string "bcd", there is no substring that does not occur in any other string.
- For the string "abcd", the shortest substring that does not occur in any other string is "abcd".

 

Constraints:

  • n == arr.length
  • 2 <= n <= 100
  • 1 <= arr[i].length <= 20
  • arr[i] consists only of lowercase English letters.

代码结果

运行时间: 125 ms, 内存: 16.7 MB


/*
 * 思路:
 * 使用Java Stream API来实现相同的逻辑。
 * 对于每个字符串,找到它的所有子字符串,
 * 然后检查这些子字符串是否存在于其他字符串中。
 * 如果某个子字符串不在其他字符串中存在,
 * 则为该字符串找到的最短且字典序最小的子字符串。
 * 否则返回空字符串。
 */
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class UniqueSubstringStream {
    public static String[] findShortestUniqueSubstring(String[] arr) {
        return IntStream.range(0, arr.length)
                .mapToObj(i -> findUniqueSubstring(arr, i))
                .toArray(String[]::new);
    }

    private static String findUniqueSubstring(String[] arr, int index) {
        String str = arr[index];
        List<String> substrings = IntStream.range(0, str.length())
                .boxed()
                .flatMap(i -> IntStream.range(i + 1, str.length() + 1)
                        .mapToObj(j -> str.substring(i, j)))
                .sorted(Comparator.comparingInt(String::length).thenComparing(Comparator.naturalOrder()))
                .collect(Collectors.toList());

        return substrings.stream()
                .filter(sub -> isUnique(sub, arr, index))
                .findFirst()
                .orElse("");
    }

    private static boolean isUnique(String sub, String[] arr, int excludeIndex) {
        return Arrays.stream(arr)
                .filter(s -> !s.equals(arr[excludeIndex]))
                .noneMatch(s -> s.contains(sub));
    }

    public static void main(String[] args) {
        String[] arr = {"cab", "ad", "bad", "c"};
        System.out.println(Arrays.toString(findShortestUniqueSubstring(arr)));
    }
}

解释

方法:

此题解采用了一种有效的方法来查找每个字符串中最短的、不是其他任何字符串子串的子字符串。方法包括创建一个哈希表来存储每个子字符串及其所属的原始字符串索引。对于数组中的每个字符串,生成所有可能的子字符串,并使用哈希表记录它们。如果一个子字符串已经存在且来自不同的字符串,则标记为公共子串。遍历完所有字符串后,再次检查哈希表中记录的子字符串,为每个字符串选择最短且字典序最小的非公共子字符串。

时间复杂度:

O(n * L^2)

空间复杂度:

O(n * L^2)

代码细节讲解

🦆
为什么将所有可能的子字符串都添加到哈希表中,而不是仅添加特定长度的子字符串?
在这个问题中,目标是找到每个字符串中最短的、不是其他字符串的子串的子字符串。若只添加特定长度的子字符串到哈希表,可能会遗漏可能的最短非公共子字符串。例如,如果仅考虑长度为3的子字符串,可能错过长度为2或更短的有效非公共子字符串。因此,添加所有可能的子字符串到哈希表可以确保不遗漏任何潜在的最短非公共子字符串。
🦆
你是如何处理哈希表中已存在的子字符串来标记为公共子字符串的?详细解释一下这个过程。
在处理过程中,当我们遇到一个新的子字符串时,首先检查它是否已经存在于哈希表中。如果已存在,并且现有记录的来源字符串索引与当前字符串的索引不同,这表明此子字符串至少出现在两个不同的字符串中,因而是一个公共子串。此时,我们将该子字符串从哈希表中删除,并将其添加到一个集合中,用于标记已知的公共子字符串。这样的处理确保了任何被多次发现的子字符串都不会被考虑为答案的一部分。
🦆
在最后选取每个字符串的最短且字典序最小的非公共子字符串时,如何确保选取的是全局最优解?
在最后的选择阶段,对于哈希表中剩余的每个非公共子字符串,我们检查其长度和字典序以确定是否更新当前字符串的结果。首先,我们检查是否已经为当前字符串找到一个非公共子字符串。如果未找到或找到的子字符串比当前子字符串长,我们则更新答案为当前子字符串。如果长度相同,我们比较并选择字典序较小的子字符串。这个过程确保了对于每个字符串,我们都选取了最短的,并在长度相同的情况下选择字典序最小的非公共子字符串,从而达到全局最优。

相关问题