class Solution {
public:
int minCut(string s) {
int n = s.size();
bool p [n][n];
memset(p,0,sizeof(bool)*n*n);
for(int i = 0;i < n;i++){
p[i][i] = true;
}
//这里DP的时候一定要注意填表的顺序。一定要先填p[i+1][j-1]再填p[i][j]
for(int i = n-1;i >= 0;i--){
for(int j = i;j < n;j++){
if(s[i] == s[j] && (j-i<2 || p[i+1][j-1])){
p[i][j] = 1;
}
}
}
queue<int> Q;
queue<int> bufQ;
Q.push(0);
int step = 0;
while(!Q.empty()){
int pos = Q.front();
Q.pop();
for(int i = 0;i < n;i++){
if(p[pos][n-1])return step;
if(p[pos][i]){
bufQ.push(i);
}
}
if(Q.empty()){
while(!bufQ.empty()){
Q.push(bufQ.front()+1);
bufQ.pop();
}
step++;
}
}
return -1;
}
};
正常的做法是DP。
这里使用的是BFS,虽然超时了,但是思想还是有价值的。
先用DP识别出来s里面所有的回文串,存放在p里。p[i][j]==1表示从s[i]到s[j]为回文串。
然后建图,p[i][j]==1表示从点i到点j有边相连。则该问题成了在无权图上寻找从点0到点n-1的最短路。可以用BFS。
需要注意的是,若从点i到点j有边,BFS时需要入队的是j+1而不是j,因为同一个字母不能同时被划到两个回文串中。下一个回文串开始处应为j+1