前言
思路及算法思维,指路 代码随想录。
题目来自 LeetCode。
day 50,周三,无法坚持~
题目详情
[1143] 最长公共子序列
题目描述
解题思路
前提:最长公共子序列,元素的相对顺序一致
思路:动态规划 dp[i][j]:以字符串text1 [0, i-1]和字符串txtx2 [0, j-1]的最长公共子序列的长度, if (text1[i-1] == text2[j-1]) dp[i][j] = dp[i-1][j-1] + 1; else dp[i][j] = max(dp[i-1][j], dp[i][j-1])
重点:递推公式的推导、dp数组初始化
代码实现
C语言
动态规划
// 动态规划 dp[i][j]:以字符串text1 [0, i-1]和字符串txtx2 [0, j-1]的最长公共子序列的长度
// if (text1[i-1] == text2[j-1]) dp[i][j] = dp[i-1][j-1] + 1
// else dp[i][j] = max(dp[i-1][j], dp[i][j-1])
int maxFun(int p1, int p2)
{
return p1 > p2 ? p1 : p2;
}
int longestCommonSubsequence(char* text1, char* text2) {
int text1_len = strlen(text1);
int text2_len = strlen(text2);
int dp[text1_len + 1][text2_len + 1];
// dp数组初始化
for (int m = 0; m <= text1_len; m++) {
dp[m][0] = 0;
}
for (int n = 1; n <= text2_len; n++) {
dp[0][n] = 0;
}
// 遍历
for (int i = 1; i <= text1_len; i++) {
for (int j = 1; j <= text2_len; j++) {
if (text1[i - 1] == text2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = maxFun(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[text1_len][text2_len];
}
[1035] 不相交的线
题目描述
解题思路
前提:转化为求最长公共子数组,且数组元素相对顺序保持一致
思路:动态规划 dp[i][j]: nums1 [0, i-1]和nums2 [0, j-1]的最长公共数组的长度, if (nums1[i-1] == nums2[j-1]) dp[i][j] = dp[i-1][j-1] + 1; else dp[i][j] = maxFun(dp[i-1][j], dp[i][j-1])
重点:递推公式的推导、dp数组初始化
代码实现
C语言
动态规划
// 动态规划 dp[i][j]: nums1 [0, i-1]和nums2 [0, j-1]的最长公共数组的长度
// if (nums1[i-1] == nums2[j-1]) dp[i][j] = dp[i-1][j-1] + 1
// else dp[i][j] = maxFun(dp[i-1][j], dp[i][j-1])
int maxFun(int p1, int p2)
{
return p1 > p2 ? p1 : p2;
}
int maxUncrossedLines(int* nums1, int nums1Size, int* nums2, int nums2Size) {
int dp[nums1Size + 1][nums2Size + 1];
// dp初始化
for (int m = 0; m <= nums1Size; m++) {
dp[m][0] = 0;
}
for (int n = 1; n <= nums2Size; n++) {
dp[0][n] = 0;
}
// 遍历
for (int i = 1; i <= nums1Size; i++) {
for (int j = 1; j <= nums2Size; j++) {
if (nums1[i - 1] == nums2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = maxFun(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[nums1Size][nums2Size];
}
[53] 最大子数组和
题目描述
解题思路
前提:最大连续子数组的和
思路:动态规划 dp[i]: 以数组的子数组[0, i]以i为结尾的最大连续子数组的和,dp[i]有两种情况: nums[i]加入子数组中; 从nums[i]重新计算,dp[i] = max(dp[i-1]+nums[i], nums[i])
重点:递推公式的推导、dp数组初始化
代码实现
C语言
动态规划
// 动态规划 dp[i]: 以数组的子数组[0, i]以i为结尾的最大连续子数组的和
// dp[i]有两种情况: nums[i]加入子数组中; 从nums[i]重新计算
// dp[i] = max(dp[i-1]+nums[i], nums[i])
int maxFun(int p1, int p2)
{
return p1 > p2 ? p1 : p2;
}
int maxSubArray(int* nums, int numsSize) {
int dp[numsSize];
int result = 0;
// dp初始化
dp[0] = nums[0];
result = dp[0];
// 遍历
for (int i = 1; i < numsSize; i++) {
dp[i] = maxFun(dp[i - 1] + nums[i], nums[i]);
result = maxFun(dp[i], result);
}
return result;
}
贪心
int maxSubArray(int* nums, int numsSize) {
int sum = 0;
int slow = 0;
int fast = 0;
int maxSum = -10001;
while (fast < numsSize) {
// 连续和为负数时,抛弃当前连续子数组和
if (sum < 0) {
sum = 0;
}
sum += nums[fast];
// 取最大和
if (sum > maxSum) {
maxSum = sum;
}
fast++;
}
return maxSum;
}
[392] 判断子序列
题目描述
解题思路
前提:化为求最长公共子序列,元素的相对顺序一致,判断最长公共子序列的长度是否与s的长度相等
思路:动态规划 dp[i][j]: 字符串s [0, i-1]和字符串t [0, j-1]的最长公共子序列,if (s[i - 1] == t[j - 1]) dp[i][j] = dp[i-1][j-1] + 1; if (s[i - 1] != t[j - 1]) dp[i][j] = dp[i][j-1],判断最长公共子序列的长度是否等于sLen
重点:递推公式的推导、dp数组初始化
代码实现
C语言
动态规划
// 动态规划 dp[i][j]: 字符串s [0, i-1]和字符串t [0, j-1]的最长公共子序列
// if (s[i - 1] == t[j - 1]) dp[i][j] = dp[i-1][j-1] + 1
// if (s[i - 1] != t[j - 1]) dp[i][j] = dp[i][j-1], 此时仅可以删除t字符串中的元素
// 判断最长公共子序列的长度是否等于sLen
bool isSubsequence(char* s, char* t) {
int sLen = strlen(s);
int tLen = strlen(t);
int dp[sLen + 1][tLen + 1];
// dp初始化
for (int m = 0; m <= sLen; m++) {
dp[m][0] = 0;
}
for (int n = 1; n <= tLen; n++) {
dp[0][n] = 0;
}
// 遍历
for (int i = 1; i <= sLen; i++) {
for (int j = 1; j <= tLen; j++) {
if (s[i - 1] == t[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] +1;
} else {
dp[i][j] = dp[i][j - 1];
}
}
}
return dp[sLen][tLen] == sLen;
}
双指针
// 双指针
bool isSubsequence(char* s, char* t) {
int sLen = strlen(s);
int tLen = strlen(t);
int slow = 0;
int fast = 0;
int count = 0;
while ((slow < sLen) && (fast < tLen)) {
if (s[slow] == t[fast]) {
count++;
slow++;
}
fast++;
}
return count == sLen;
}
今日收获
- 动态规划