还原原始字符串 | 豆包MarsCode AI 刷题

95 阅读3分钟

43 还原原始字符串

问题描述

给定字符串 S,用一个任意可变整数 K(< S.length)执行若干次以下操作:
S=S+S[k:S.length]
但是我们不知道最开始的 S 是什么。给定最终的字符串 F,输出起始字符串中最短的结果。

假设输入 F:aabbcc
k=3 时,执行第一次操作后,得到的是 S 为:aabbccbcc
接着让 k=6,在上述 S 基础上,再执行一次 k=6 时的操作,得到新 S 为:aabbccbccbcc

豆包回复

将此问题直接询问豆包,得到结果如下。
要解决这个问题,我们需要找到一个最短的起始字符串 S,使得通过一系列操作可以得到给定的最终字符串 F。我们可以通过以下步骤来解决这个问题:

  1. 理解问题

    • 给定一个最终字符串 F,我们需要找到一个最短的起始字符串 S,使得通过一系列操作可以得到 F
    • 操作是:选择一个整数 K,将 SS[k: S.length] 拼接起来,得到新的 S
  2. 关键点

    • 我们需要找到一个最短的 S,使得通过一系列操作可以生成 F
    • 这意味着 S 应该是 F 的一个前缀,并且这个前缀可以通过重复自身来生成 F
  3. 数据结构选择

    • 我们可以使用字符串操作来找到最短的前缀。
  4. 算法步骤

    • 遍历 F 的所有可能的前缀。
    • 对于每个前缀,检查它是否可以通过重复自身来生成 F
    • 找到最短的前缀,使得它可以生成 F

通过以上步骤,我们可以找到最短的起始字符串 S,使得通过一系列操作可以得到给定的最终字符串 F。 可以发现,Ai将问题错误理解为S的重复是完全重复,而不是可选择的局部重复。但是暴力的整体思路不变。

思路分析

一开始考虑暴力解法,即依次遍历整个字符串,每次判别字符串是否可以通过重复生成F,如果可以,则此时则为最短的结果。

  • 遍历 F 的所有可能的前缀。
  • 对于每个前缀,检查它是否可以通过重复自身来生成 F

实现代码

public class Main {

    public static String solution(String str1) {
        // Edit your code here
        if(!str1.equals("")) {
            for(int i = 1; i <= str1.length(); i++){
                String str = str1.substring(0,i);
                if(isMeet(str,str1)){
                    return str;
                }
            }
        }
        return "";
    }

    public static boolean isMeet(String str, String target) {
        if (!target.startsWith(str)) {
            return false;
        } else {
            if (str.length() == target.length()) {
                return true;
            }
        }
        for (int i = 0; i < str.length(); i++) {
            int count = str.length();
            if (str.length() < target.length())
                str = str + str.substring(i);
            if (isMeet(str, target)) {
                return true;
            } else {
                str = str.substring(0,count);
            }
        }
        return false;
    }

    public static void main(String[] args) {
        // Add your test cases here

        System.out.println(solution("abbabbbabb").equals("ab"));
        System.out.println(solution("abbbabbbb").equals("ab"));
        System.out.println(solution("jiabanbananananiabanbananananbananananiabanbananananbananananbananananbanananan").equals("jiaban"));
        System.out.println(solution("selectecttectelectecttectcttectselectecttectelectecttectcttectectelectecttectcttectectcttectectcttectectcttect").equals("select"));
        System.out.println(solution("discussssscussssiscussssscussssdiscussssscussssiscussssscussssiscussssscussss").equals("discus"));
    }
}

改进思路

从字符串F出发,可以发现F的末尾字符一定也是原始字符的末尾字符。
例如初始S = "abc",则它不管重复多少次,它的结果字符必定满足末尾字符为c。 根据这一思路,上述代码中的依次遍历字符串则只需查找满足末尾字符等于F的末尾字符的子字符串,然后进行比较。


public class Main {

    public static String solution(String str1) {
        // Edit your code here
        int n = str1.length();
        int count = 0;
        if(!str1.equals("")) {
            char c = str1.charAt(n - 1);
            while (true) {
                int index = str1.indexOf(c, count++);
                String str = str1.substring(0, index + 1);
                if (isMeet(str, str1)) {
                    return str;
                }
            }
        }
        return "";
    }

    public static boolean isMeet(String str, String target) {
        if (!target.startsWith(str)) {
            return false;
        } else {
            if (str.length() == target.length()) {
                return true;
            }
        }
        for (int i = 0; i < str.length(); i++) {
            int count = str.length();
            if (str.length() < target.length())
                str = str + str.substring(i);
            if (isMeet(str, target)) {
                return true;
            } else {
                str = str.substring(0,count);
            }
        }
        return false;
    }

    public static void main(String[] args) {
        // Add your test cases here

        System.out.println(solution("abbabbbabb").equals("ab"));
        System.out.println(solution("abbbabbbb").equals("ab"));
        System.out.println(solution("jiabanbananananiabanbananananbananananiabanbananananbananananbananananbanananan").equals("jiaban"));
        System.out.println(solution("selectecttectelectecttectcttectselectecttectelectecttectcttectectelectecttectcttectectcttectectcttectectcttect").equals("select"));
        System.out.println(solution("discussssscussssiscussssscussssdiscussssscussssiscussssscussssiscussssscussss").equals("discus"));
    }
}