---
# System prepended metadata

title: 0131. Palindrome Partitioning
tags: [Leetcode, DFS, Medium, Backtracking]

---

# 0131. Palindrome Partitioning
###### tags: `Leetcode` `Medium` `Backtracking` `DFS`
Link: https://leetcode.com/problems/palindrome-partitioning/
## 思路
### 思路一 Pure Backtracking $O(N*2^N)$ $O(N)$
从start pos开始找出所有可能的子字串，一个一个检查是不是palindrome，如果是就加进答案，继续遍历
Each substring will take $O(N)$ time to check if it's palindrom and $O(N)$ time to generate substring from start to end indexes. 所以实际上是$O(2N*2^N)$
### 思路二 Backtracking+Dynamic Programming $O(N*2^N)$ $O(N)$
先用dp table记录所有palindrome，这样就不需要重复遍历了
for each palindrom we still need $O(N)$ time to generate substring from start to end indexes. The complexity is still the same $O(N*2^N)$ 但是会更省时间，因为是$O(N*2^N)$

## Code
### 思路一
```python=
class Solution:
    def partition(self, s: str) -> List[List[str]]:
        ans = []

        def isPalindrome(start, end):
            left, right = start, end
            while left<right:
                if s[left]!=s[right]:
                    return False
                left += 1
                right -= 1
            return True

        def backtracking(curr, start):
            if start == len(s): 
                ans.append(curr[:])
            else:
                for i in range(start, len(s)):
                    if isPalindrome(start, i):
                        curr.append(s[start:i+1])
                        backtracking(curr, i+1)
                        curr.pop()
                
        backtracking([], 0)
        return ans
```
```java=
class Solution {
    public List<List<String>> partition(String s) {
        List<List<String>> ans = new ArrayList<>();
        List<String> result = new ArrayList<>();
        backtracking(ans, result, 0, s);
        return ans;
    }
    private void backtracking(List<List<String>> ans, List<String> result, int start, String s){
        if(start == s.length()){
            ans.add(new ArrayList<String>(result));
            return;
        }
        for(int i = start;i < s.length();i++){
            if(isPalindrome(s,start,i)){
                result.add(s.substring(start, i+1));
                backtracking(ans, result, i+1, s);
                result.remove(result.size()-1);
            }
        }
    }
    private boolean isPalindrome(String s, int start, int end){
        if(start==end) return true;
        while(start<end){
            if(s.charAt(start)!=s.charAt(end)) return false;
            start++;
            end--;
        }
        return true;
    }
}
```
### 思路二
```java=
class Solution {
    List<List<String>> ans;
    public List<List<String>> partition(String s) {
        ans = new ArrayList<>();
        int n = s.length();
        boolean[][] dp = new boolean[n][n];
        for(int i=0; i<n; i++) dp[i][i] = true;
        for(int len=2; len<=n; len++){
            for(int i=0; i+len-1<n; i++){
                int j = i+len-1;
                if(s.charAt(i)==s.charAt(j)){
                    if(j==i+1) dp[i][j] = true;
                    else if(dp[i+1][j-1]) dp[i][j] = true;
                }
            }
        }
        
        List<String> curr = new ArrayList<>();
        dfs(s, 0, dp, curr);
        return ans;
    }
    private void dfs(String s, int start, boolean[][] dp, List<String> curr){
        if(start>=s.length()){
            ans.add(new ArrayList<>(curr));
        }
        for(int i=start; i<s.length(); i++){
            if(!dp[start][i]) continue;
            curr.add(s.substring(start, i+1));
            dfs(s, i+1, dp, curr);
            curr.remove(curr.size()-1);
        }
    }
}
```