📜  最长的子串 - Java (1)

📅  最后修改于: 2023-12-03 15:10:37.819000             🧑  作者: Mango

最长的子串 - Java

当涉及到字符串处理时,找到其最长的子串是一个常见的问题。在Java中,有几种方法可以解决这个问题,其中包括暴力解法、滑动窗口和动态规划等。

暴力解法

暴力解法是最简单的解法,但是它的时间复杂度很高,需要O(n^3)的时间才能找到最长的子串。该方法的思路是从字符串的开头开始,获取所有可能的子串,然后通过比较它们的长度找到最长的子串。下面是一个示例代码:

public static String longestSubstring(String s) {
    String longest = "";
    for (int i = 0; i < s.length(); i++) {
        for (int j = i + 1; j <= s.length(); j++) {
            if (s.substring(i, j).length() > longest.length() && isUnique(s.substring(i, j))) {
                longest = s.substring(i, j);
            }
        }
    }
    return longest;
}

private static boolean isUnique(String s) {
    HashSet<Character> set = new HashSet<>();
    for (char c : s.toCharArray()) {
        if (!set.add(c)) return false;
    }
    return true;
}
滑动窗口

滑动窗口是另一种方法,它可以在不重复遍历所有子串的情况下找到最长的子串。该方法的思路是将一个窗口放置在字符串的开头,并将其向右滑动,直到与窗口重叠的子串不重复为止。然后将窗口扩大并再次滑动,直到找到最长的子串。下面是一个示例代码:

public static String longestSubstring(String s) {
    int i = 0, j = 0;
    String longest = "";
    HashSet<Character> set = new HashSet<>();
    while (j < s.length()) {
        if (!set.contains(s.charAt(j))) {
            set.add(s.charAt(j++));
            longest = Math.max(longest.length(), j - i) == j - i ? s.substring(i, j) : longest;
        } else {
            set.remove(s.charAt(i++));
        }
    }
    return longest;
}
动态规划

动态规划是另一种更高效的解法。它使用一个二维数组来保存最长子串的长度。该数组的行代表字符串中的字母,而列代表字母的数量。当填充数组时,可以使用一个变量来记录最长子串的长度,并在每次更新数组时进行比较。下面是一个示例代码:

public static String longestSubstring(String s) {
    int i = 0, j = 0, maxLength = 0;
    boolean[] bitSet = new boolean[256];
    String longest = "";
    while (j < s.length()) {
        if (!bitSet[s.charAt(j)]) {
            bitSet[s.charAt(j++)] = true;
            maxLength = Math.max(maxLength, j - i);
            longest = maxLength == j - i ? s.substring(i, j) : longest;
        } else {
            bitSet[s.charAt(i++)] = false;
        }
    }
    return longest;
}

无论使用哪种方法,确保测试你的代码以确保它可以正常工作。