-2

I am wondering how to optimize my solution to the LeetCode question: 5. Longest palindromic substring:

Given a string s, return the longest palindromic substring in s.

I get Time Limit exceeded on really long strings (up to 1000 characters), but on the other hand, using the same long string on my terminal gives me the correct answer instantly. Here is a string on which I get the error:

"zudfweormatjycujjirzjpyrmaxurectxrtqedmmgergwdvjmjtstdhcihacqnothgttgqfywcpgnuvwglvfiuxteopoyizgehkwuvvkqxbnufkcbodlhdmbqyghkojrgokpwdhtdrwmvdegwycecrgjvuexlguayzcammupgeskrvpthrmwqaqsdcgycdupykppiyhwzwcplivjnnvwhqkkxildtyjltklcokcrgqnnwzzeuqioyahqpuskkpbxhvzvqyhlegmoviogzwuiqahiouhnecjwysmtarjjdjqdrkljawzasriouuiqkcwwqsxifbndjmyprdozhwaoibpqrthpcjphgsfbeqrqqoqiqqdicvybzxhklehzzapbvcyleljawowluqgxxwlrymzojshlwkmzwpixgfjljkmwdtjeabgyrpbqyyykmoaqdambpkyyvukalbrzoyoufjqeftniddsfqnilxlplselqatdgjziphvrbokofvuerpsvqmzakbyzxtxvyanvjpfyvyiivqusfrsufjanmfibgrkwtiuoykiavpbqeyfsuteuxxjiyxvlvgmehycdvxdorpepmsinvmyzeqeiikajopqedyopirmhymozernxzaueljjrhcsofwyddkpnvcvzixdjknikyhzmstvbducjcoyoeoaqruuewclzqqqxzpgykrkygxnmlsrjudoaejxkipkgmcoqtxhelvsizgdwdyjwuumazxfstoaxeqqxoqezakdqjwpkrbldpcbbxexquqrznavcrprnydufsidakvrpuzgfisdxreldbqfizngtrilnbqboxwmwienlkmmiuifrvytukcqcpeqdwwucymgvyrektsnfijdcdoawbcwkkjkqwzffnuqituihjaklvthulmcjrhqcyzvekzqlxgddjoir"

Below you can find my solution to the problem where i use two functions.

  1. ispalindrome (boolean) to check wheather a given string is a palindrome.
  2. longestpalindrome(): The algorithm that uses sliding window to check wheather the string provdided is the longest palindrome.
class Solution {
public:
  bool ispalindrome(string s) {
    int i = 0, j = s.size() - 1;
    while(i <= j){
      if(s[i] != s[j]){
        return false;
      }
      i++;
      j--;
    }
    return true;
  }
  string longestPalindrome(string s) {
    int window_size = s.size() - 1;
    int left = 0, right = window_size;
    string tmp_str = "";
    while (right < s.size()) {
      tmp_str.append(s.begin() + left, s.begin() + right + 1);
      if (ispalindrome(tmp_str)) {
        return tmp_str;
      }
      if((right + 1) < s.size()) {
        tmp_str = "";
        right++;
        left++;
      } else {
        tmp_str = "";
        window_size--;
        right = window_size;
        left = 0;
      }
    }
    return s;
  }
};
  • 2
    You are doing way too much copying of strings. Probably should not copy it a single time. – drescherjm Feb 18 '22 at 17:59
  • 1
    Your solution is correct, but you need to use dynamic programming to avoid unnecessary recalculations. Check this out: https://www.youtube.com/watch?v=PY9sl9QZqSs&t=1673s – Ari Feb 18 '22 at 18:03

1 Answers1

0

The algorithm loses a lot of time by working from the outside inwards. Realise that a palindrome has a "center" (on, or between neighboring indexes), and your algorithm will often look for palindromes using the same center but with decreasing sizes. You could reduce work by working from the inside out, i.e. select all possible centers, and see what the largest palindrome is that has that center. This way you will only do one scan per center. So, iterate over all possible centers (both on indexes, and between two indexes), and see which is the largest palindrome you can find this way.

You can then further optimise by starting with centers in the middle of the string (since they can potentially offer the largest strings), and then "fan" your center away from the middle of the string, until you come too close to an outer end of the string, making it impossible to improve on the longest palindrome that you had already found.

Finally, avoid creating new strings, and just work with indexes (left, right, ...etc), and only really create a string when you already have identified the start/end index of the largest palindrome.

Dharman
  • 30,962
  • 25
  • 85
  • 135
trincot
  • 317,000
  • 35
  • 244
  • 286