千年难遇回文日小纪

     天阴沉的很,骤寒,很平常的一天。

    拔了几根鸭毛,坏了个手指甲儿,而后就还是一如既往的宅着因为冠状病毒,一整天解几个bug苦闷调试伴无眠,一天也就要这么过去了。

   过去的这么一年,还清了所有外债,响应号召让娃上了省公办托育园,写了几篇博客,开源项目后来带娃没什么空断断续续的没什么时间整了,总的来说,越来越好吧!

    就写这么多吧,但愿早日拨开云雾见月明吧,武汉加油!

PTA(Programming Teaching Assistant)最小回文数是一个常见的算法问题,其目标是通过给定的字符串,经过最少次数的插入操作,使得字符串变成一个回文字符串。回文字符串是指正读和反读都相同的字符串。 解决这个问题的基本思路是通过动态规划或贪心算法,遍历字符串的同时检查每个字符的位置,保证从左到右和从右到左的字符是匹配的。如果遇到不匹配的情况,就需要插入字符,使得整个字符串成为回文串。通常,我们可以选择在左边或者右边插入字符,但是为了保证插入次数最少,我们需要选择一个更合理的位置进行插入。 具体来说,可以使用以下步骤: 1. 初始化一个二维数组 `dp`,其中 `dp[i][j]` 表示字符串从第 `i` 个字符到第 `j` 个字符变为回文串需要的最小插入次数。 2. 对于长度为 `n` 的字符串,遍历所有可能的子串长度,即对每个 `l` 从 `2` 到 `n`,再对每个子串的起始位置 `i` 从 `0` 到 `n-l`,计算 `dp[i][i+l-1]`。 3. 对于子串 `str[i...j]`: - 如果 `str[i] == str[j]`,则 `dp[i][j] = dp[i+1][j-1]`,因为两端的字符已经匹配,不需要额外操作。 - 如果 `str[i] != str[j]`,需要插入一个字符来匹配两端,`dp[i][j] = min(dp[i+1][j], dp[i][j-1]) + 1`,分别表示在左端或右端插入字符后,剩下的子串需要的最小插入次数加一。 4. 最终结果存储在 `dp[0][n-1]` 中,即整个字符串变为回文串需要的最小插入次数。 5. 通过回溯 `dp` 数组,可以找到具体的插入位置。 这里提供一个简化的代码示例,用于说明思路,并非完整的代码实现: ```c #include <stdio.h> #include <string.h> int minInsertions(char *str) { int n = strlen(str); int dp[n][n]; // 初始化动态规划数组 for (int i = 0; i < n; i++) { dp[i][i] = 0; // 单个字符的子串已经是回文串,不需要插入 } // 动态规划填表 for (int l = 2; l <= n; l++) { // 子串长度从2开始 for (int i = 0; i <= n - l; i++) { // 子串起始位置 int j = i + l - 1; // 子串结束位置 if (str[i] == str[j]) { dp[i][j] = dp[i + 1][j - 1]; } else { dp[i][j] = fmin(dp[i + 1][j], dp[i][j - 1]) + 1; } } } return dp[0][n - 1]; // 整个字符串变为回文串需要的最小插入次数 } int main() { char str[] = "abca"; printf("Minimum insertions to make string palindrome: %d\n", minInsertions(str)); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值