目录
1143.最长公共子序列
题目链接:1143. 最长公共子序列
在前一天的718. 最长重复子数组 相当类似,这个题目有印象童咏昕老师的算法课里面有将!
int longestCommonSubsequence(char * text1, char * text2){
int size1=strlen(text1)+1,size2=strlen(text2)+1;
int dp[size1][size2];
int ret=0;
//初始化j=0
for(int i=0;i<size1;i++){
dp[i][0]=0;
}
//初始化i=0
for(int j=0;j<size2;j++){
dp[0][j]=0;
}
for(int i=1;i<size1;i++){
for(int j=1;j<size2;j++){
if(text1[i-1]==text2[j-1]){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=fmax(dp[i-1][j],dp[i][j-1]);
}
ret=fmax(ret,dp[i][j]);
}
}
return ret;
}
1035.不相交的线
题目链接:1035. 不相交的线
与上面一题1143.最长公共子序列 如出一辙。
从末尾往前考虑,得到递推公式:
- 如果两数相等:i,j都往前回退一个再进行判断,即dp[i][j]=dp[i-1][j-1]+1;
- 如果两数不相等:分两种情况,i往前回退一个,或者j往前回退一个,取两者最大值,即:dp[i][j]=fmax(dp[i-1][j],dp[i][j-1]);
int maxUncrossedLines(int* nums1, int nums1Size, int* nums2, int nums2Size){
int dp[nums1Size+1][nums2Size+1];
for(int i=0;i<=nums1Size;i++){
dp[i][0]=0;
}
for(int j=0;j<=nums2Size;j++){
dp[0][j]=0;
}
int ret=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]=fmax(dp[i-1][j],dp[i][j-1]);
}
ret=fmax(ret,dp[i][j]);
}
}
return ret;
}
53. 最大子序和
题目链接:53. 最大子数组和
这个题目太多种解法
1. 动态规划(比较好想)
//动态规划
int maxSubArray(int* nums, int numsSize){
int* dp=(int*)malloc(sizeof(int)*numsSize);
dp[0]=nums[0];
int ret=dp[0];
for(int i=1;i<numsSize;i++){
dp[i]=fmax(dp[i-1]+nums[i],nums[i]);
ret=(dp[i]>ret)?dp[i]:ret;
}
return ret;
}
2.贪心
//贪心
int maxSubArray(int* nums, int numsSize){
int ret=INT_MIN;
int sum=0;
for(int i=0;i<numsSize;i++){
sum+=nums[i];
if(sum>ret) ret=sum;
if(sum<0) sum=0;
}
return ret;
}
3.分治(高要求)
int CrossingSubArray(int* nums,int low,int mid,int high){
int max_left=INT_MIN,max_right=INT_MIN;
int sum=0;
for(int i=mid;i>=low;i--){
sum+=nums[i];
max_left=fmax(sum,max_left);
}
sum=0;
for(int i=mid+1;i<=high;i++){
sum+=nums[i];
max_right=fmax(sum,max_right);
}
return max_left+max_right;
}
int maxArray(int* nums, int low,int high){
if(low==high) return nums[low];
int mid=(low+high)/2;
//分(左闭右闭)
int S1=maxArray(nums,low,mid);
int S2=maxArray(nums,mid+1,high);
//治
int S3=CrossingSubArray(nums,low,mid,high);
//比较最大值
int max=fmax(S1,S2);
max=fmax(max,S3);
return max;
}
int maxSubArray(int* nums, int numsSize){
int max=maxArray(nums,0,numsSize-1);
return max;
}