动态规划求子序列和子串问题

倾然丶 夕夏残阳落幕 提交于 2020-03-17 06:39:25

LeetCode子序列问题:300. 最长上升子序列673. 最长递增子序列的个数1143. 最长公共子序列516. 最长回文子序列

LeetCode子串问题: 5. 最长回文子串14. 最长公共前缀

300. 最长上升子序列

int max(int a,int b){
    return a>b?a:b;
}
int lengthOfLIS(int* nums, int numsSize){
    int i,j,rst=0;
    int dp[numsSize+1];
    if(numsSize<=1)return numsSize;
    for(i=0;i<numsSize;i++){
        dp[i]=1;
        for(j=0;j<i;j++){
            if(nums[i]>nums[j]){
                dp[i]=max(dp[i],dp[j]+1);
            }
            if(rst<dp[i])rst=dp[i];
        }
    }
    return rst;
}

673. 最长递增子序列的个数

int max(int a,int b){
    return a>b?a:b;
}
int findNumberOfLIS(int* nums, int numsSize){
    int i,j,dp[numsSize+1],maxnum=0,cnt[numsSize+1];
    if(numsSize<=1)return numsSize;
    for(i=0;i<numsSize;i++){
        dp[i]=1;cnt[i]=1;
        for(j=0;j<i;j++){
            if(nums[i]>nums[j]){
                if(dp[i]<(dp[j]+1))
                {dp[i]=dp[j]+1;cnt[i]=cnt[j];}
                else if(dp[i]==(dp[j]+1))
                    cnt[i]+=cnt[j];
            }
            if(maxnum<dp[i])maxnum=dp[i];//计算z最大递增子序列长度
        }
    }
    int sum=0;
    for(i=0;i<numsSize;i++){//计算递增长度为d最大的子序列总和
        if(maxnum==dp[i])
            sum+=cnt[i];
    }
    return sum;
}

1143. 最长公共子序列

int max(int a,int b){
    return a>b?a:b;
}
int longestCommonSubsequence(char * text1, char * text2){
    int i,j,len1,len2;
    len1=strlen(text1);len2=strlen(text2);
    int dp[len1+1][len2+1];
    for(i=0;i<=len1;i++)
        dp[i][0]=0;
    for(i=0;i<=len2;i++)
        dp[0][i]=0;
    for(i=1;i<=len1;i++){
        for(j=1;j<=len2;j++){
            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]);
        }
    }
    return dp[len1][len2];
}

516. 最长回文子序列

int max(int a,int b){
    return a>b?a:b;
}
int longestPalindromeSubseq(char * s){
    int i,j,len;
    len=strlen(s);
    int dp[len][len];
    memset(dp,0,sizeof(dp));
    if(len==0)
        return 0;
    for(i=0;i<len;i++){
        dp[i][i]=1;
    }
    for(i=len-1;i>=0;i--){
        for(j=i+1;j<len;j++){
            if(s[i]==s[j])
                dp[i][j]=dp[i+1][j-1]+2;
            else
                dp[i][j]=max(dp[i+1][j],dp[i][j-1]);
        }
    }
    return dp[0][len-1];
}

 

5. 最长回文子串

char * longestPalindrome(char * s){
    int i,j;
    int dp[1001][1001];
    int left=0,right=0;
    int len = strlen(s);
    if(len<=1||s==NULL)//判断特殊情况
        return s;
    //思路很简单,对于这类dp问题,一定是先处理特例,分情况讨论。并且大问题可以通过子问题来解决。
    memset(dp,0,sizeof(dp));
    for(i=0;i<len;i++){//单个字符串一定是回文字符串
           dp[i][i]=1;
    }
    for(i=len-2;i>=0;i--){//由于后面使用到dp[i+1][j-1],那么必须保证i是递减i遍历而j是递增遍历,这样dp[i+1][j-1]一定是在dp[i][j]之前已经判断过的
        for(j=i+1;j<len;j++){
            if(j-i<2){
                if(s[i]==s[j])
                    dp[i][j]=1;
                else
                    dp[i][j]=0;
            }else{
                if(s[i]==s[j])
                    dp[i][j]=dp[i+1][j-1];
                else
                    dp[i][j]=0;   
            }
            if(dp[i][j] && (right-left)<(j-i)){
                left=i;
                right=j;
            }
        }
    }
    char *dest=(char*)malloc(10000);
    memset(dest, '\0', sizeof(dest));
    strncpy(dest, s+left, right-left+1);
    dest[right-left+1]='\0';
    return dest;
}

14. 最长公共前缀

char * longestCommonPrefix(char ** strs, int strsSize){
    int i,j,minm,tmp;
    char *son=(char*)malloc(1000);
    memset(son,'\0',sizeof(son));
    if(strsSize==0)
    {
        son[0]='\0';
    }else{
        minm=strlen(strs[0]);
        for(i=1;i<strsSize;i++){//找出字符串最短长度
            if(minm>strlen(strs[i]))
                minm=strlen(strs[i]);
        }
        for(j=0;j<minm;j++){//垂直比较,比较所有字符串第j个字母是否相同
            tmp=strs[0][j]-'a';
            for(i=1;i<strsSize;i++){
                if(tmp!=(strs[i][j]-'a'))
                break;
            }
            if(i<strsSize)
                break;
        }
        strncpy(son,strs[0],j);
        son[j]='\0';
   }
    return son;
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!