LeetCode1392 最长快乐前缀题解

LeetCode1392 最长快乐前缀

题目

「快乐前缀」是在原字符串中既是 非空 前缀也是后缀(不包括原字符串自身)的字符串。
给你一个字符串 s,请你返回它的 最长快乐前缀。
如果不存在满足题意的前缀,则返回一个空字符串。

举例子:

  1. 示例 1:
    输入:s = “level”
    输出:“l”

  2. 示例 2:
    输入:s = “ababab”
    输出:“abab”。

  3. 示例 3:
    输入:s = “leetcodeleet”
    输出:“leet”

  4. 示例 4:
    输入:s = “a”
    输出:""

解题思路

思想一 暴力解法

毫无疑问用暴力解法可以进行求解,对字符串进行遍历,在第i次时判断字符串前i个字符是否与后i个字符相同,如果相同则是一个快乐前缀,遍历到最后找到最长的快乐前缀即可。

思想二 动态规划思想

思想是定义一个一维数组kmp[],他的大小与字符串大小相同,kmp[i]的值记录了字符串前i+1个字符(因为数组从0开始)组成的字符串的最长快乐前缀,而题目需要的答案即为字符串的前kmp[string.length-1]个字符组成的字符串。

具体讲一下过程:

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200825171830346.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpemVmZW5nMTk5OA==,size_16,color_FFFFFF,t_70#pic_cente

以这幅图介绍一下第一种情况,当要计算string[5]的kmp值时,发现前五个字符组成的字符串的最长快乐前缀是aba(因为kmp[4]=3),而我们能够发现string[3]恰好等于当前的string[5],也就是字符b,因此kmp[5]就等于kmp[4]+1。

在这里插入图片描述
而如果当前字符不能和之前的字符继续构成快乐前缀怎么办呢,例如将第一幅图最后的字符b改成了字符a,在这种情况下,我们就要去寻找之前的字符串的最长快乐子串,而这种情况的中心思想是,这个字符既然不能和之前的最长快乐前缀构成快乐前缀,那么是否可以和之前的最长的快乐前缀的最长快乐前缀构成快乐前缀,具体的话举下面的一个例子:

在这里插入图片描述

以下标24及之前的字符构成的字符串的一个快乐前缀是下标20开始的"aabaa",而下一个字符是b,不等于string[5],因此就要寻找"aabaa"的最长快乐前缀。而因为字符串"aabaa"是快乐前缀,因此在原字符串的开头的前五位是“aabaa”,他的最长快乐前缀长度存储在kmp数组中,kmp[4] = 2。下一步需要判断当前字符’b’是否能与"aa"组成快乐前缀,即判断string[25]是否等于string[2](这个2是因为"aa"长度是2),因为"aab"构成了快乐前缀,因此kmp[25]就等于3(’‘aa’'的长度是2,'b’的长度是1)。
用这样的思路就可以构建出来kmp数组,题目也就解出来了。

代码展示

这里只展示动态规划的代码:

	public static String longestPrefix(String s) {
        if(s.length()==0)
            return "";
        if(s.length()==1)
            return "";
        char string[] = s.toCharArray();
        int kmp[] = new int[s.length()];
        kmp[0] = 0;
        for (int i=1;i< kmp.length;i++)
        {
            if (string[kmp[i-1]]==string[i])
            {
                kmp[i] = kmp[i-1] + 1;
            }
            else
            {
                if(kmp[i-1]==0)
                {
                    if(string[i]==string[0])
                        kmp[i] = 1;
                    else
                        kmp[i] = 0;
                    continue;
                }
                int temp = kmp[i-1];
                int a = kmp[temp-1];
                char b = string[a];
                if(b==string[i]&&kmp[i-1]!=0)
                {
                    kmp[i] = a+1;
                }
                else
                {
                    if(string[i]==string[0])
                        kmp[i] = 1;
                    else
                        kmp[i] = 0;
                }
            }
        }
        int index = kmp[string.length-1];
        StringBuffer sb = new StringBuffer();
        for (int i=0;i<index;i++)
        {
            sb.append(string[i]);
        }
        return sb.toString();
    }

如果觉得这篇题解有用的话就给我点个赞吧,有什么也可以在评论区交流交流~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值