Sharing answer codes of mine about HackerRank: Short Palindrome.

HackerRank: Short Palindrome (in Algorithm)

Problem Statement

Consider a string, \(s\), of \(n\) lowercase English letters where each character, \(s_i (0\leq i < n)\), denotes the letter at index \(i\) in \(s\). We define an \((a,b,c,d)\) palindromic tuple of \(s\) to be a sequence of indices in \(s\) satisfying the following criteria:

  • \(s_a = s_d\), meaning the characters located at indices \(a\) and \(d\) are the same.
  • \(s_b = s_c\), meaning the characters located at indices \(b\) and \(c\) are the same.
  • \(0\leq a< b< c< d< \mid s \mid\), meaning that \(a, b, c,\) and \(d\) are ascending in value and are valid indices within string \(s\).

Given \(s\), find and print the number of \((a,b,c,d)\) tuples satisfying the above conditions. As this value can be quite large, print it modulo \(10^9+7\).

Naive Answer Code (in Python3)

  • Time complexity: \(O(n^3)\)
# Time complexity: O(n^3)
#!/bin/python3

import sys
import string

def shortPalindrome(s):
    mod = pow(10,9)+7
    cnt = 0

    for i in range(len(s)):
        for j in range(i+1, len(s)):
            for k in range(j+1, len(s)):
                if s[j]==s[k]:
                    cnt += s[k+1:].count(s[i])

    return cnt % mod

if __name__ == "__main__":
    s = input().strip()
    result = shortPalindrome(s)
    print(result)

Final Answer Code (in Python3)

  • Time complexity: \(O(n)\)
# Time complexity: O(n)
#!/bin/python3

import sys
import string

def shortPalindrome(input_string):
    c_dic = dict(zip(string.ascii_lowercase, range(26)))  # ascii value dict for every alphabet
    ip_ascii = [c_dic[i] for i in input_string]  # change input as ascii value
    one_c = [0] * 26  # for one character occurred (e.g. a)
    two_c = [[0] * 26 for _ in range(26)]  # for two chracter occurred (e.g. ab)
    thr_c = [0] * 26  # for three chracter occured following the rule (e.g. abb)
    total = 0

    for current in ip_ascii:
        # sum the number of matching palindrome when the last character is 'current' (e.g. abba)
        total += thr_c[current]
        for i in range(26):  # for every alphabet, sum the number of sequence such as 'abb'
            thr_c[i] += two_c[i][current]
        for i in range(26):  # for every alphabet, sum the number of sequence such as 'ab'
            two_c[i][current] += one_c[i]
        one_c[current] += 1  # Count the occurred character

    return total % (10 ** 9 + 7)

if __name__ == "__main__":
    s = input().strip()
    result = shortPalindrome(s)
    print(result)