目录
前言
A.建议
1.学习算法最重要的是理解算法的每一步,而不是记住算法。
2.建议读者学习算法的时候,自己手动一步一步地运行算法。
B.简介
在C语言中,实现分割回文串的算法通常会涉及到寻找所有可能的分割点,并检查这些子串是否都是回文。对于题目“131.分割回文串”,目标是找到最少的分割次数使得每个分割得到的子串都是回文串。
一 代码实现
思路一:动态规划(DP)
动态规划方法可以用来求解最少分割次数。创建一个数组dp[]
,其中dp[i]
表示字符串s
的前i
个字符所需的最小分割次数。
#include <stdio.h>
#include <string.h>
bool isPalindrome(char* s, int start, int end) {
// 写一个辅助函数判断子串是否为回文
while (start < end) {
if (s[start] != s[end]) return false;
start++;
end--;
}
return true;
}
int minCut(char* s) {
int n = strlen(s);
int dp[n]; // dp[i] 表示以s[i]结尾的子串的最小切割次数
bool palindrome[n][n]; // 动态构建一个矩阵来存储所有子串是否为回文
// 初始化
for (int i = 0; i < n; ++i) {
dp[i] = i; // 最坏情况,每个字符单独作为一个子串
palindrome[i][i] = true; // 单个字符总是回文
}
// 构建回文矩阵
for (int L = 2; L <= n; ++L) {
for (int i = 0; i < n - L + 1; ++i) {
int j = i + L - 1;
if (isPalindrome(s, i, j)) {
palindrome[i][j] = true;
dp[j] = (i == 0) ? 0 : dp[i-1];
} else {
dp[j] = INT_MAX;
for (int k = i; k < j; ++k) {
if (palindrome[i][k] && palindrome[k+1][j] && dp[k+1] < INT_MAX) {
dp[j] = dp[k+1] + 1;
break;
}
}
}
}
}
return dp[n - 1];
}
int main() {
char s[] = "aab";
printf("Minimum cuts needed: %d\n", minCut(s));
return 0;
}
思路二:深度优先搜索(DFS)或广度优先搜索(BFS)
另一种思路是通过遍历所有可能的分割方式,然后利用递归或队列结构进行深度优先搜索或广度优先搜索,找出满足条件的最少分割数。这种方法相对复杂且效率较低,因为需要穷举所有分割方案。
#include <stdio.h>
#include <stdbool.h&