Leetcode P0131"Palindrome Partitioning" 题解

2020/09/12 Leetcode

博文中会简要介绍Leetcode P0131题目分析及解题思路。

“Palindrome Partitioning”这道题主要考察的是深度优先搜索的思想,这里运用了递归回溯的方法。我们可以直接暴力判断当前子串是否是回文串,也可以通过使用动态规划的方法先得到每个子串是否是回文串,然后再递归回溯求解。

Given a string s, partition s such that every substring of the partition is a palindrome.

Return all possible palindrome partitioning of s.

Example:

Input: "aab"
Output:
[
  ["aa","b"],
  ["a","a","b"]
]

以下是Java的题解代码实现。

class Solution {
    public List<List<String>> partition(String s) {
        int N = s.length();
        
        boolean[][] dp = new boolean[N][N];
        char[] chars = s.toCharArray();
        for (int idx=0; idx<N; ++idx) {
            dp[idx][idx] = true;
            if (idx > 0 && chars[idx] == chars[idx-1])
                dp[idx-1][idx] = true;
        }
        
        // DP
        for (int i1=2; i1<N; ++i1) {
            for (int j2=i1-2; j2>=0; --j2) {
                dp[j2][i1] = dp[j2+1][i1-1] && (chars[i1] == chars[j2]);
            }
        }
        
        this.dfs(0, N, s, dp, new ArrayList<>());
        return this.partitions;
    }
    
    private List<List<String>> partitions = new ArrayList<>();
        
    private void dfs(int left, int N, String s, boolean[][] dp, List<String> partitioning) {
        if (left >= N) {
            this.partitions.add(new ArrayList<>(partitioning));
            return;
        }
        
        for (int right=left; right<N; ++right) {
            if (!dp[left][right])
                continue;
            
            partitioning.add(s.substring(left, right+1));
            this.dfs(right+1, N, s, dp, partitioning);
            partitioning.remove(partitioning.size()-1);
        }
    }
}

以下是C++的题解代码实现。

class Solution {
public:
    vector<vector<string>> partition(string s) {
        int L = s.length();
        
        vector<string> partitioning;
        this->_Dfs(0, s, L, partitioning);
        return this->partitions_;
    }
    
private:
    vector<vector<string>> partitions_;
    
    void _Dfs(int left, const string s, const int L, vector<string> &partitioning) {
        if (left >= L) {
            this->partitions_.push_back(vector<string>(partitioning));
            return;
        }
        
        for (int right=left; right<L; ++right) {
            if (!this->_Check(s, left, right))
                continue;
            
            partitioning.push_back(s.substr(left, right-left+1));
            this->_Dfs(right+1, s, L, partitioning);
            partitioning.pop_back();
        }
    }
    
    bool _Check(string s, int left, int right) {
        while (left < right) {
            if (s[left] != s[right])
                return false;
            
            ++left;
            --right;
        }
        
        return true;
    }
};

Search

    Table of Contents