09. Longest Periodic Proper Prefix
โ GFG solution to the Longest Periodic Proper Prefix problem: find the length of longest periodic proper prefix using Z-algorithm technique. ๐
The problem can be found at the following link: ๐ Question Link
๐งฉ Problem Description
Given a string s
, find the length of the longest periodic proper prefix of s
. If no such prefix exists, return -1
.
A periodic proper prefix is a non-empty prefix of s
(but not the whole string), such that repeating this prefix enough times produces a string that starts with s
.
๐ Examples
Example 1
Input: s = "aaaaaa"
Output: 5
Explanation: Repeating the proper prefix "aaaaa" forms "aaaaaaaaaa...", which contains "aaaaaa" as a prefix. No longer proper prefix satisfies this.
Example 2
Input: s = "abcab"
Output: 3
Explanation: Repeating the proper prefix "abc" forms "abcabc...", which contains "abcab" as a prefix. No longer proper prefix satisfies this.
Example 3
Input: s = "ababd"
Output: -1
Explanation: No proper prefix satisfying the given condition.
๐ Constraints
$1 \le s.size() \le 10^5$
s
consists of lowercase English alphabets
โ
My Approach
The optimal approach uses the Z-algorithm to efficiently find all positions where a prefix of the string matches a suffix starting at that position:
Z-Algorithm Based Solution
Z-Array Construction:
Build a Z-array where
z[i]
represents the length of the longest substring starting froms[i]
which is also a prefix ofs
.Use the efficient Z-algorithm with left (
l
) and right (r
) pointers to maintain the rightmost Z-box.
Key Insight:
For a periodic proper prefix, we need to find the largest index
i
such that:z[i] == n - i
(the suffix starting at positioni
matches the prefix)i < n
(ensuring it's a proper prefix, not the entire string)
Algorithm Steps:
Initialize
z[0] = 0
(by convention, as we start from index 1).For each position
i
from 1 to n-1:If
i
is within the current Z-box (i <= r
), use previously computed values.Extend the match as far as possible using character comparisons.
Update the Z-box boundaries if necessary.
Check if
z[i] == n - i
and update the answer.
Finding the Answer:
Iterate through all positions and find the largest
i
wherez[i] == n - i
.This indicates that the prefix of length
i
is periodic.
๐ Time and Auxiliary Space Complexity
Expected Time Complexity: O(n), where n is the length of the string. The Z-algorithm processes each character at most twice due to the sliding window approach with left and right pointers.
Expected Auxiliary Space Complexity: O(n), as we maintain a Z-array of size n to store the Z-values for each position.
๐งโ๐ป Code (C++)
class Solution {
public:
int getLongestPrefix(string s) {
int n = s.size(), l = 0, r = 0, ans = -1;
vector<int> z(n);
for (int i = 1; i < n; i++) {
if (i <= r) z[i] = min(r - i + 1, z[i - l]);
while (i + z[i] < n && s[z[i]] == s[i + z[i]]) z[i]++;
if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1;
if (z[i] == n - i) ans = i;
}
return ans;
}
};
โ Code (Java)
class Solution {
int getLongestPrefix(String s) {
int n = s.length(), l = 0, r = 0, ans = -1;
int[] z = new int[n];
for (int i = 1; i < n; i++) {
if (i <= r) z[i] = Math.min(r - i + 1, z[i - l]);
while (i + z[i] < n && s.charAt(z[i]) == s.charAt(i + z[i])) z[i]++;
if (i + z[i] - 1 > r) { l = i; r = i + z[i] - 1; }
if (z[i] == n - i) ans = i;
}
return ans;
}
}
๐ Code (Python)
class Solution:
def getLongestPrefix(self, s):
n, l, r, ans = len(s), 0, 0, -1
z = [0] * n
for i in range(1, n):
if i <= r:
z[i] = min(r - i + 1, z[i - l])
while i + z[i] < n and s[z[i]] == s[i + z[i]]:
z[i] += 1
if i + z[i] - 1 > r:
l, r = i, i + z[i] - 1
if z[i] == n - i:
ans = i
return ans
๐ง Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: ๐ฌ Any Questions?. Let's make this learning journey more collaborative!
โญ If you find this helpful, please give this repository a star! โญ
๐Visitor Count
Last updated