都有哪些js素材网站国内好的seo
目录
- 题目描述
- 输入输出示例及数据范围
- 思路
- C++ 实现
题目描述
这道题目来自 LeetCode 131. 分割回文串。
题目描述如下:
给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。
输入输出示例及数据范围
思路
这道题的类型被归为回溯,实际上这道题目并不是一步回溯就能够解决的,在回溯之前,我们需要先对整个字符串进行预处理。
这道题目的要求是让我们对原字符串进行分割,分割的结果是若干个子串,且每个子串都是回文串。
那么我们解决这道题目的思路就是,对于子串s[i...j]
,加入它是回文串,就把它加入到答案当中,假定字符串的长度为n
,我们现在要进一步解决的问题是寻找s[j+1...n]
的子串,进行分割,并将结果加入到答案当中。
当然,我们可以简单地使用双指针不断地枚举子串的范围,并判断范围内的子串是否是回文串,但是显然这种解法的时间复杂度过高。
一个更快的思路是,首先我们使用 dp 对回文串进行预处理,新开一个二维数组f
,如果f[i][j] == true
,则表明子串s[i...j]
是回文串,此时可以将子串s[i...j]
加入到答案当中,下一次回溯从j+1
开始。
C++ 实现
class Solution {
public:vector<vector<string>> ans;vector<vector<bool>> f;vector<string> curr;int n;void solve(string &s, int i) {if(i == s.size()) {ans.push_back(curr);return;}for(int j=i; j<n; j++) {if(f[i][j]) {curr.push_back(s.substr(i, j - i + 1));solve(s, j + 1);curr.pop_back();}}}vector<vector<string>> partition(string s) {n = s.size();f.assign(n, vector<bool>(n, true));for(int i=n-1; i>=0; i--) {for(int j=i+1; j<n; j++) { // 对回文串进行预处理f[i][j] = (s[i] == s[j]) && f[i + 1][j - 1];}}solve(s, 0);return ans;}
};