Skip to content

1392. Longest Happy Prefix 👍

  • Time: $O(n)$
  • Space: $O(1)$
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution {
 public:
  string longestPrefix(string s) {
    constexpr int kBase = 26;
    constexpr int kMod = 1'000'000'007;
    const int n = s.length();
    int maxLength = 0;
    long pow = 1;
    long prefixHash = 0;  // Hash of s[0..i]
    long suffixHash = 0;  // Hash of s[j..n)

    for (int i = 0, j = n - 1; i < n - 1; ++i, --j) {
      prefixHash = (prefixHash * kBase + val(s[i])) % kMod;
      suffixHash = (val(s[j]) * pow + suffixHash) % kMod;
      pow = pow * kBase % kMod;
      if (prefixHash == suffixHash)
        maxLength = i + 1;
    }

    return s.substr(0, maxLength);
  }

 private:
  int val(char c) {
    return c - 'a';
  }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution {
  public String longestPrefix(String s) {
    final int kBase = 26;
    final int kMod = 1_000_000_007;
    final int n = s.length();
    int maxLength = 0;
    long pow = 1;
    long prefixHash = 0; // Hash of s[0..i]
    long suffixHash = 0; // Hash of s[j..n)

    for (int i = 0, j = n - 1; i < n - 1; ++i, --j) {
      prefixHash = (prefixHash * kBase + val(s.charAt(i))) % kMod;
      suffixHash = (val(s.charAt(j)) * pow + suffixHash) % kMod;
      pow = pow * kBase % kMod;
      if (prefixHash == suffixHash)
        maxLength = i + 1;
    }

    return s.substring(0, maxLength);
  }

  private int val(char c) {
    return c - 'a';
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution:
  def longestPrefix(self, s: str) -> str:
    kBase = 26
    kMod = 1_000_000_007
    n = len(s)
    maxLength = 0
    pow = 1
    prefixHash = 0  # Hash of s[0..i]
    suffixHash = 0  # Hash of s[j..n)

    def val(c: str) -> int:
      return ord(c) - ord('a')

    j = n - 1
    for i in range(n - 1):
      prefixHash = (prefixHash * kBase + val(s[i])) % kMod
      suffixHash = (val(s[j]) * pow + suffixHash) % kMod
      pow = pow * kBase % kMod
      if prefixHash == suffixHash:
        maxLength = i + 1
      j -= 1

    return s[:maxLength]