# Longest Palindromic Substring (Linear)
A palindrome is a word, phrase, or sequence that reads the same backward as forward, e.g.,
'madam' or 'racecar'. Even the letter 'x' is considered a palindrome. 
For this Kata, you are given a string ```s```. Write a function that returns the longest _contiguous_ palindromic substring in ```s``` (it could be the entire string). In the event that there are multiple longest palindromic substrings, return the first to occur.
I'm not trying to trick you here:
- You can assume that all inputs are valid strings.
- Only the letters a-z will be used, all lowercase (your solution should, in theory, extend to more than just the letters a-z though). 
**NOTE:** Quadratic asymptotic complexity _(O(N^2))_ or above will __NOT__ work here.
-----
## Examples
### Basic Tests
```
Input: "babad"
Output: "bab"
(Note: "bab" occurs before "aba")
```
```
Input: "abababa"
Output: "abababa"
```
```
Input: "cbbd"
Output: "bb"
```
### Edge Cases
```
Input: "ab"
Output: "a"
```
```
Input: ""
Output: ""
```
-----
## Testing
Along with the example tests given:
 - There are **500** tests using strings of length in range [1 - 1,000]
 - There are **50** tests using strings of length in range [1,000 - 10,000]
 - There are **5** tests using strings of length in range [10,000 - 100,000]
All test cases can be passed within 10 seconds, but non-linear solutions will time out every time. _Linear performance is essential_. 
## Good Luck!
-----
This problem was inspired by [this](https://leetcode.com/problems/longest-palindromic-substring/) challenge on LeetCode. Except this is the performance version :^)
'''
    Write a function that returns the longest contiguous palindromic substring in s. 
    In the event that there are multiple longest palindromic substrings, return the 
    first to occur.
'''

# TODO: Complete in linear time xDD
def longest_palindrome(s):
    if is_palindrome(s):
        return s
        
    max_pal = ''

    for i in range(len(s)):
        temp = check(i, i, s)
        if len(max_pal) < len(temp):
            max_pal = temp

    return max_pal


def check(li, ri, s):
    if li > 0 and ri < len(s):
        if is_palindrome(s[li - 1: ri + 2]):
            return check(li - 1, ri + 1, s)
        elif is_palindrome(s[li: ri + 2]):
            return check(li, ri + 1, s)
        elif is_palindrome(s[li - 1: ri + 1]):
            return check(li - 1, ri, s)

    return s[li: ri + 1]


def is_palindrome(s):
    return s == s[::-1]
'''
    Write a function that returns the longest contiguous palindromic substring in s. 
    In the event that there are multiple longest palindromic substrings, return the 
    first to occur.
'''

# TODO: Complete in linear time xDD
def longest_palindrome(s):
    if is_palindrome(s):
        return s
        
    max_pal = ''

    for i in range(len(s)):
        temp = check(i, i, s)
        if len(max_pal) < len(temp):
            max_pal = temp

    return max_pal


def check(li, ri, s):
    if li > 0 and ri < len(s):
        if is_palindrome(s[li - 1: ri + 2]):
            return check(li - 1, ri + 1, s)
        elif is_palindrome(s[li: ri + 2]):
            return check(li, ri + 1, s)
        elif is_palindrome(s[li - 1: ri + 1]):
            return check(li - 1, ri, s)

    return s[li: ri + 1]


def is_palindrome(s):
    return s == s[::-1]