Skip to content

Palindrome Partitioning⚓︎

Link

Description⚓︎

Given a string s, partition s such that every substring of the partition is a palindrome. Return all possible palindrome partitioning of s.

A substring is a contiguous non-empty sequence of characters within a string. A palindrome is a string that reads the same forward and backward.

Example 1:

  • Input: s = "aab"
  • Output: [["a","a","b"],["aa","b"]]

Example 2:

  • Input: s = "a"
  • Output: [["a"]]

Constraints:

  • 1 <= s.length <= 16
  • s contains only lowercase English letters.

Solution⚓︎

Way 1⚓︎

class Solution {
private:
    vector<vector<string>> res;
    vector<string> path;

    void backtracking(string &s, int index) {
        if (index == s.length()) {
            res.push_back(path);
            return;
        }

        for (int i = index; i < s.length(); i++) {
            if (!isPalindrome(s, index, i)) continue;
            path.push_back(s.substr(index, i - index + 1));
            backtracking(s, i + 1);
            path.pop_back();
        }
    }

    bool isPalindrome(string &s, int l, int r) {
        while (l < r) {
            if (s[l] != s[r]) return false;
            l++, r--;
        }
        return true;
    }

public:
    vector<vector<string>> partition(string s) {
        backtracking(s, 0);
        return res;
    }
};
  • Time complexity: \(O(n\cdot 2^n)\);
  • Space complexity: \(O(n^2)\).

Way 2: Optimized Solution⚓︎

class Solution {
private:
    vector<vector<string>> res;
    vector<string> path;
    vector<vector<bool>> isPalindrome; 

    void backtracking(const string &s, int index) {
        if (index == s.length()) {
            res.push_back(path);
            return;
        }
        for (int i = index; i < s.length(); i++) {
            if (!isPalindrome[index][i]) continue;
            path.push_back(s.substr(index, i - index + 1));
            backtracking(s, i + 1);
            path.pop_back();
        }
    }

    void computeMemo(const string &s) {
        isPalindrome.resize(s.size(), vector<bool>(s.size(), false));
        for (int i = s.size() - 1; i >= 0; i--) {
            for (int j = i; j < s.size(); j++) {
                if (j == i) isPalindrome[i][j] = true;
                else if (j - i == 1) isPalindrome[i][j] = (s[i] == s[j]);
                else isPalindrome[i][j] = (s[i] == s[j] && isPalindrome[i + 1][j - 1]);
            }
        }
    }
public:
    vector<vector<string>> partition(string s) {
        computeMemo(s);
        backtracking(s, 0);
        return res;
    }
};