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
28
class Solution {
 public:
  string longestPrefix(string s) {
    constexpr int kBase = 26;
    constexpr long kHash = 8'417'508'174'513;

    const int n = s.length();
    int maxLength = 0;
    long pow = 1;
    long prefixHash = 0;  // the hash of s[0..i]
    long suffixHash = 0;  // the hash of s[j..n)

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

    return s.substr(0, maxLength);
  }

 private:
  constexpr 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 BASE = 26;
    final long HASH = 8_417_508_174_513L;
    final int n = s.length();
    int maxLength = 0;
    long pow = 1;
    long prefixHash = 0; // the hash of s[0..i]
    long suffixHash = 0; // the hash of s[j..n)

    for (int i = 0, j = n - 1; i < n - 1; ++i, --j) {
      prefixHash = (prefixHash * BASE + val(s.charAt(i))) % HASH;
      suffixHash = (val(s.charAt(j)) * pow + suffixHash) % HASH;
      pow = pow * BASE % HASH;
      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:
    BASE = 26
    HASH = 8_417_508_174_513
    n = len(s)
    maxLength = 0
    pow = 1
    prefixHash = 0  # the hash of s[0..i]
    suffixHash = 0  # the 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 * BASE + val(s[i])) % HASH
      suffixHash = (val(s[j]) * pow + suffixHash) % HASH
      pow = pow * BASE % HASH
      if prefixHash == suffixHash:
        maxLength = i + 1
      j -= 1

    return s[:maxLength]