[LeetCode 131] 回文分割(Palindrome Partitioning)

问题

给定一个字符串s,切割s使该切割结果中每一个子串都是一个回文。

返回所有可能的回文分割集合。

例如,如果有s = "aab",

返回

[a,a,b]

[aa,b]

初始思路

有了回文分割II(Palindrome Partitioning II)的经验,这里很容易就可以得到递归分解子集的方案。只是在回文分割II中我们是统计切割次数,而这里要保存分割出来的子串。这里需要再强调一次枚举一个集合所有分割可能的经典递归循环,基本所有分割类问题都会用到:

if(start < s.size())
{
    size_t pos = start;
        
    while(pos < s.size())
    {
        //入栈
        MakePartition(result, oneResult, s, pos + 1);
        //出栈

        ++pos;
    }
}
else
{
    //得到一个解
}

具体到本问题,我们可以用一个vector保存一个解。于是上面的入栈操作就对应于push_back当前子串,出栈操作对应于pop_back,而得到一个解就对应于把该vector push_back到一个保存所有分割的二维vector中。

那么最终代码就出来了:

class Solution {
public:
    vector<vector<string>> partition(string s) {
        std::vector<std::vector<std::string>> result;
        std::vector<std::string> oneResult;
    
        MakePartition(result, oneResult, s, 0);
    
        return result;
    }
    
private:
    void MakePartition(std::vector<std::vector<std::string>>& result, std::vector<std::string>& oneResult, const std::string& s, size_t start)
    {
        if(start < s.size())
        {
            size_t pos = start;
        
            while(pos < s.size())
            {
                if(IsPalindrome(s, start, pos))
                {
                    oneResult.push_back(s.substr(start, pos - start + 1));
                    MakePartition(result, oneResult, s, pos + 1);
                    oneResult.pop_back();
                }
                ++pos;
            }
        }
        else
        {
            result.push_back(oneResult);
        }

    }

    bool IsPalindrome(const std::string& s, size_t start, size_t end)
    {
        bool result = true;
    
        while(start < end)
        {
            if(s[start] != s[end])
            {
                result = false;
                break;
            }       
            ++start;
            --end;
        }    
        return result;
    }
};

提交后Judge Large 52毫秒通过,看来这种枚举所有可能的问题优化空间不算太多。

原文地址:https://www.cnblogs.com/shawnhue/p/leetcode_131.html