前言
思路及算法思维,指路 代码随想录。
题目来自 LeetCode。
day 52,周五,开始补作业了~
题目详情
[647] 回文子串
题目描述
647 回文子串
解题思路
前提:寻找回文子串,子串意味着元素连续
思路:动态规划 寻找dp数组之间有联系的推导关系, dp[i][j]: 字符串中[i, j]子串是否为回文子串,s[i] == s[j]时, 3种情况, ij时,true, i+1j时,true, j>i+1时,dp[i][j] = dp[i+1][j-1], s[i] != s[j]时, dp[i][j] = false,统计dp数组中true的数量
重点:dp数组的定义、递推公式的推导、回文子串的条件判断
代码实现
C语言
动态规划
// 动态规划 dp[i][j]: 字符串中[i, j]子串是否为回文子串
// s[i] == s[j]时, 3种情况, i==j时,true, i+1==j时,true, j>i+1时,dp[i][j] = dp[i+1][j-1]
// s[i] != s[j]时, dp[i][j] = false
// 统计dp数组中true的数量int countSubstrings(char* s) {int sLen = strlen(s);bool dp[sLen][sLen];int count = 0;// 遍历for (int i = sLen - 1; i >= 0; i--) {for (int j = i; j < sLen; j++) {if (j == i) {dp[i][j] = true;} else if (j == i + 1) {if (s[i] == s[j]) {dp[i][j] = true;} else {dp[i][j] = false;}} else {if (s[i] == s[j]) {dp[i][j] = dp[i + 1][j - 1];} else {dp[i][j] = false;}}if (dp[i][j] == true) {count++;}}}return count;
}
双指针
// 双指针: 2种情况
// 以单个元素为核心向两边扩展,寻找回文子串的个数
// 以两个元素为核心向两边扩展,寻找回文子串的个数int checkSubStrings(char *s, int sLen, int i, int j)
{int res = 0; while (i >= 0 && j < sLen && s[i] == s[j]) {res++;i--;j++;}return res;
}int countSubstrings(char* s) {int sLen = strlen(s);int count = 0;for (int i = 0; i < sLen; i++) {// 单元素为核心count += checkSubStrings(s, sLen, i, i);// 双元素为核心count += checkSubStrings(s, sLen, i, i + 1);}return count;
}
[516] 最长回文子序列
题目描述
516 最长回文子序列
解题思路
前提:寻找最长回文子序列,子序列意味着元素可以不连续,元素相对顺序一致即可
思路:动态规划 dp[i][j]: 字符串在[i, j]中最长回文子序列的长度,分为两种情况,s[i] == s[j]时, dp[i][j] = dp[i+1][j-1] + 2;s[i] != s[j]时, 分别尝试将s[i]/s[j]加入,判断是否为回文子序列,取最大值, dp[i][j] = max(dp[i][j-1], dp[i+1][j])
重点:dp数组的定义、递推公式的推导、回文子串的条件判断
代码实现
C语言
动态规划
// 动态规划 dp[i][j]: 字符串在[i, j]中最长回文子序列的长度
// 分为两种情况
// s[i] == s[j]时, dp[i][j] = dp[i+1][j-1] + 2;
// s[i] != s[j]时, 分别尝试将s[i]/s[j]加入,判断是否为回文子序列,取最大值, dp[i][j] = max(dp[i][j-1], dp[i+1][j])int maxFun(int p1, int p2)
{return p1 > p2 ? p1 : p2;
}int longestPalindromeSubseq(char* s) {int sLen = strlen(s);int dp[sLen][sLen];// dp初始化for (int i = 0; i < sLen; i++) {for (int j = 0; j < sLen; j++) {dp[i][j] = 0;}dp[i][i] = 1;}// 遍历for (int i = sLen - 1; i >= 0; i--) {for (int j = i + 1; j < sLen; j++) {if (s[i] == s[j]) {dp[i][j] = dp[i + 1][j - 1] + 2;} else {dp[i][j] = maxFun(dp[i + 1][j], dp[i][j - 1]);}}}return dp[0][sLen - 1];
}
今日收获
- 动态规划