【Leetcode】1392. Longest Happy Prefix

題目地址:

https://leetcode.com/problems/longest-happy-prefix/

給定一個字符串,其長度爲kk的前綴和長度爲kk後綴有可能相等,問最大的kk對應的那個前綴是什麼。

題目本質上是求KMP算法中的next數組(KMP有個原始版本和優化版本,這裏指的是原始版本。對於原始版本,n[i]n[i]表示s[0:i1]s[0:i-1]中最長相等前後綴的長度,規定n[0]=1n[0]=-1)。

我們考慮n[i]n[i]n[i1]n[i-1]的遞推關係。
首先n[1]=0n[1]=0,我們是可以確定的。對於n[i1]n[i-1],假設n[i1]=tn[i-1]=t,意味着s[0:t1]=s[it1:i2]s[0:t-1]=s[i-t-1:i-2]

1、若s[i1]=s[t]s[i-1]=s[t],那麼就有s[0:t]=s[it1:i1]s[0:t]=s[i-t-1:i-1],所以n[i]t+1n[i]\ge t+1。但如果n[i]>t+1n[i]>t+1的話,就會導致s[0:t+1]=s[it2:i1]s[0:t+1]=s[i-t-2:i-1],從而有s[0:t]=s[it2:i2]s[0:t]=s[i-t-2:i-2],這與n[i1]=tn[i-1]=t矛盾了,所以有n[i]=t+1n[i]= t+1

2、若s[i1]s[t]s[i-1]\ne s[t],根據next數組的定義,s[i1]s[i-1]要繼續和s[n[t]]s[n[t]]進行比較,如果不等,則繼續和s[n[n[t]]]s[n[n[t]]]進行比較,如此這樣下去,直到與s[i1]=s[nk[t]]s[i-1]=s[n^k[t]]相等爲止,相等後,n[i]=nk[t]+1n[i]=n^k[t]+1;若一直都不等,則n[i]=n[0]+1=1+1=0n[i]=n[0]+1=-1+1=0,也是對的。證明與1類似。代碼如下:

public class Solution {
    public String longestPrefix(String s) {
        if (s == null || s.isEmpty()) {
            return "";
        }
        // 因爲要求的是s的最長相等前後綴的長度,所以要多開一個長度
        int[] next = new int[s.length() + 1];
        next[0] = -1;
        
        int i = 0, j = -1;
        while (i < s.length()) {
            while (j != -1 && s.charAt(i) != s.charAt(j)) {
                j = next[j];
            }
            i++;
            j++;
            next[i] = j;
        }
        
        return s.substring(0, next[s.length()]);
    }
}

時空複雜度O(n)O(n)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章