mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-10 04:06:51 +08:00
@ -206,6 +206,65 @@ public:
|
||||
return result;
|
||||
}
|
||||
};
|
||||
```
|
||||
# 优化
|
||||
|
||||
上面的代码还存在一定的优化空间, 在于如何更高效的计算一个子字符串是否是回文字串。上述代码```isPalindrome```函数运用双指针的方法来判定对于一个字符串```s```, 给定起始下标和终止下标, 截取出的子字符串是否是回文字串。但是其中有一定的重复计算存在:
|
||||
|
||||
例如给定字符串```"abcde"```, 在已知```"bcd"```不是回文字串时, 不再需要去双指针操作```"abcde"```而可以直接判定它一定不是回文字串。
|
||||
|
||||
具体来说, 给定一个字符串`s`, 长度为```n```, 它成为回文字串的充分必要条件是```s[0] == s[n-1]```且```s[1:n-1]```是回文字串。
|
||||
|
||||
大家如果熟悉动态规划这种算法的话, 我们可以高效地事先一次性计算出, 针对一个字符串```s```, 它的任何子串是否是回文字串, 然后在我们的回溯函数中直接查询即可, 省去了双指针移动判定这一步骤.
|
||||
|
||||
具体参考代码如下:
|
||||
|
||||
```CPP
|
||||
class Solution {
|
||||
private:
|
||||
vector<vector<string>> result;
|
||||
vector<string> path; // 放已经回文的子串
|
||||
vector<vector<bool>> isPalindrome; // 放事先计算好的是否回文子串的结果
|
||||
void backtracking (const string& s, int startIndex) {
|
||||
// 如果起始位置已经大于s的大小,说明已经找到了一组分割方案了
|
||||
if (startIndex >= s.size()) {
|
||||
result.push_back(path);
|
||||
return;
|
||||
}
|
||||
for (int i = startIndex; i < s.size(); i++) {
|
||||
if (isPalindrome[startIndex][i]) { // 是回文子串
|
||||
// 获取[startIndex,i]在s中的子串
|
||||
string str = s.substr(startIndex, i - startIndex + 1);
|
||||
path.push_back(str);
|
||||
} else { // 不是回文,跳过
|
||||
continue;
|
||||
}
|
||||
backtracking(s, i + 1); // 寻找i+1为起始位置的子串
|
||||
path.pop_back(); // 回溯过程,弹出本次已经填在的子串
|
||||
}
|
||||
}
|
||||
void computePalindrome(const string& s) {
|
||||
// isPalindrome[i][j] 代表 s[i:j](双边包括)是否是回文字串
|
||||
isPalindrome.resize(s.size(), vector<bool>(s.size(), false)); // 根据字符串s, 刷新布尔矩阵的大小
|
||||
for (int i = s.size() - 1; i >= 0; i--) {
|
||||
// 需要倒序计算, 保证在i行时, i+1行已经计算好了
|
||||
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) {
|
||||
result.clear();
|
||||
path.clear();
|
||||
computePalindrome(s);
|
||||
backtracking(s, 0);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
# 总结
|
||||
|
Reference in New Issue
Block a user