LeetCode刷题6-找出符合要求的字符串子串()

package com.example.demo.leetcode.case202208;

import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

/**
 * 功能描述
 *
 * @author ASUS
 * @version 1.0
 * @Date 2022/8/5
 */
public class Main2022080502 {
    /*
    查找两个字符串a,b中的最长公共子串。若有多个,输出在较短串中最先出现的那个。
    注:子串的定义:将一个字符串删去前缀和后缀(也可以不删)形成的字符串。请和“子序列”的概念分开!

    数据范围:字符串长度1≤length≤300
    进阶:时间复杂度:O(n^3) ,空间复杂度:O(n)

    输入描述:
    输入两个字符串

    输出描述:
    返回重复出现的字符
    示例1
    输入
    abcdefghijklmnop
    abcsafjklmnopqrstuvw
    输出
    jklmnop
    */
    public static void main(String[] args) {
        // 获取输入的字符串
        Scanner scanner = new Scanner(System.in);
        String s1 = scanner.nextLine();
        String s2 = scanner.nextLine();

        // 字符串的所有子串
        LinkedHashSet<String> set1 = getSubStr(s1);
        LinkedHashSet<String> set2 = getSubStr(s2);

        // 获取所有公共子串
        List<String> commSubStr = getCommSubStr(s1, s2, set1, set2);

        // 公共子串的最大长度
        int max = 1;
        for (String str : commSubStr
        ) {
            max = getMaxCommonLength(str, max);
        }

        // 最大字串长度的所有公共子串集合
        List<String> newList = new LinkedList<>();
        for (String str : commSubStr
        ) {
            getMaxSubStrList(max, str, newList);
        }
        System.out.println(newList.get(0));
    }

    /**
     * 满足最大字串长度的所有公共子串集合 -有顺序
     *
     * @param max
     * @param str
     * @param comList
     * @return
     */
    private static List<String> getMaxSubStrList(int max, String str, List<String> comList) {
        if (str.length() >= max) {
            comList.add(str);
        }
        return comList;
    }

    /**
     * 公共子串的最大长度
     *
     * @param str
     * @param max
     * @return
     */
    private static int getMaxCommonLength(String str, int max) {
        if (str.length() >= max) {
            max = str.length();
        }
        return max;
    }

    /**
     * 获取2个字符串所有公共子串
     *
     * @param s1
     * @param s2
     * @param set1
     * @param set2
     * @return
     */
    private static List<String> getCommSubStr(String s1, String s2, LinkedHashSet<String> set1, LinkedHashSet<String> set2) {
        // 需要知道哪个字符串长度最小
        LinkedHashSet<String> min = s1.length() <= s2.length() ? set1 : set2;
        LinkedHashSet<String> max = s1.length() <= s2.length() ? set2 : set1;
        // 最大的公共子串长度不会超过最小的字符串长度 获取2个字符串所有公共子串
        List<String> newList = new LinkedList<>();
        min.forEach(s -> {
            if (max.contains(s)) {
                newList.add(s);
            }
        });
        return newList;
    }

    /**
     * 字符串的所有子串
     *
     * @param str
     * @return
     */
    private static LinkedHashSet<String> getSubStr(String str) {
        LinkedHashSet<String> set = new LinkedHashSet<>();
        for (int i = 0; i < str.length(); i++) {
            for (int j = i + 1; j <= str.length(); j++) {
                set.add(str.substring(i, j));
            }
        }
        return set;
    }
}
————————
package com.example.demo.leetcode.case202208;

import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

/**
 * 功能描述
 *
 * @author ASUS
 * @version 1.0
 * @Date 2022/8/5
 */
public class Main2022080502 {
    /*
    查找两个字符串a,b中的最长公共子串。若有多个,输出在较短串中最先出现的那个。
    注:子串的定义:将一个字符串删去前缀和后缀(也可以不删)形成的字符串。请和“子序列”的概念分开!

    数据范围:字符串长度1≤length≤300
    进阶:时间复杂度:O(n^3) ,空间复杂度:O(n)

    输入描述:
    输入两个字符串

    输出描述:
    返回重复出现的字符
    示例1
    输入
    abcdefghijklmnop
    abcsafjklmnopqrstuvw
    输出
    jklmnop
    */
    public static void main(String[] args) {
        // 获取输入的字符串
        Scanner scanner = new Scanner(System.in);
        String s1 = scanner.nextLine();
        String s2 = scanner.nextLine();

        // 字符串的所有子串
        LinkedHashSet<String> set1 = getSubStr(s1);
        LinkedHashSet<String> set2 = getSubStr(s2);

        // 获取所有公共子串
        List<String> commSubStr = getCommSubStr(s1, s2, set1, set2);

        // 公共子串的最大长度
        int max = 1;
        for (String str : commSubStr
        ) {
            max = getMaxCommonLength(str, max);
        }

        // 最大字串长度的所有公共子串集合
        List<String> newList = new LinkedList<>();
        for (String str : commSubStr
        ) {
            getMaxSubStrList(max, str, newList);
        }
        System.out.println(newList.get(0));
    }

    /**
     * 满足最大字串长度的所有公共子串集合 -有顺序
     *
     * @param max
     * @param str
     * @param comList
     * @return
     */
    private static List<String> getMaxSubStrList(int max, String str, List<String> comList) {
        if (str.length() >= max) {
            comList.add(str);
        }
        return comList;
    }

    /**
     * 公共子串的最大长度
     *
     * @param str
     * @param max
     * @return
     */
    private static int getMaxCommonLength(String str, int max) {
        if (str.length() >= max) {
            max = str.length();
        }
        return max;
    }

    /**
     * 获取2个字符串所有公共子串
     *
     * @param s1
     * @param s2
     * @param set1
     * @param set2
     * @return
     */
    private static List<String> getCommSubStr(String s1, String s2, LinkedHashSet<String> set1, LinkedHashSet<String> set2) {
        // 需要知道哪个字符串长度最小
        LinkedHashSet<String> min = s1.length() <= s2.length() ? set1 : set2;
        LinkedHashSet<String> max = s1.length() <= s2.length() ? set2 : set1;
        // 最大的公共子串长度不会超过最小的字符串长度 获取2个字符串所有公共子串
        List<String> newList = new LinkedList<>();
        min.forEach(s -> {
            if (max.contains(s)) {
                newList.add(s);
            }
        });
        return newList;
    }

    /**
     * 字符串的所有子串
     *
     * @param str
     * @return
     */
    private static LinkedHashSet<String> getSubStr(String str) {
        LinkedHashSet<String> set = new LinkedHashSet<>();
        for (int i = 0; i < str.length(); i++) {
            for (int j = i + 1; j <= str.length(); j++) {
                set.add(str.substring(i, j));
            }
        }
        return set;
    }
}