在线编程四

来源:互联网 发布:mac dock栏设置 编辑:程序博客网 时间:2024/06/06 11:08

1.求最长递增子序列
给定:arr=[2,1,5,3,6,4,8,9,7];
得到:[1,3,4,8,9]

#include<iostream>#include<vector>using namespace std;/**********************************************///时间复杂度 n^2vector<int> getdp(vector<int> arr){    int n=arr.size();    vector<int> dp(n);    for(int i=0;i<n;i++)    {        dp[i]=1;        for(int j=0;j<i;j++)        {            if(arr[i]>arr[j])                dp[i]=max(dp[i],dp[j]+1);        }    }    return dp;}vector<int> lis(vector<int> arr,vector<int> dp){    int n=dp[0];    int flag;    for(int i=1;i<dp.size();i++)    {        if(dp[i]>n)        {            n=dp[i];            flag=i;        }    }    vector<int> res(n);    res[n-1]=arr[flag];    int count=1;    for(int i=flag-1;i>=0;i--)    {           if((dp[i]==dp[flag]-1) && arr[i]<arr[flag])        {            flag=i;count++;            res[n-count]=arr[i];        }    }    return res;}/**********************************************//**********************************************///时间复杂度 n*lgnvector<int> getdp1(vector<int> arr){    int n=arr.size();    vector<int> dp(n);    vector<int> end(n);    int right=0;    dp[0]=1;end[0]=arr[0];    int l=0,m=0,r=0;    for(int i=1;i<n;i++)    {        l=0;        r=right;        while(l<=r)        {            m=(l+r)/2;            if(arr[i]>end[m])            {                l=m+1;            }            else            {                r=m-1;            }        }        right=max(right,l);        end[l]=arr[i];        dp[i]=l+1;    }    return dp;}/**********************************************/int main(){    vector<int> arr;    arr.push_back(2);    arr.push_back(1);    arr.push_back(5);    arr.push_back(3);    arr.push_back(6);    arr.push_back(4);    arr.push_back(8);    arr.push_back(9);    arr.push_back(7);    vector<int> dp;    dp=getdp1(arr);    vector<int> res=lis(arr,dp);    for(int i=0;i<res.size();i++)        cout<<res[i]<<" ";    return 0;}

2.最长公共子序列
输入: string a=”A12C3D4B56”;
string b=”B1D23CA45B6A”;
输出:123456或者12C4B6

#include<iostream>#include<vector>#include<string>using namespace std;vector<vector<int>> getdp(string a,string b){    int m=a.size();    int n=b.size();    vector<vector<int>> dp(m,vector<int>(n));    dp[0][0]=a[0]==b[0]?1:0;    for(int i=1;i<m;i++)    {        dp[i][0]=max(a[i]==b[0]?1:0,dp[i-1][0]);    }    for(int j=1;j<n;j++)    {        dp[0][j]=max(a[0]==b[j]?1:0,dp[0][j-1]);    }    for(int i=1;i<m;i++)        for(int j=1;j<n;j++)        {            dp[i][j]=max(dp[i-1][j],dp[i][j-1]);            if(a[i]==b[j])            {                dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);            }        }        return dp;}string lcse(string a,string b,vector<vector<int>> dp){    int m=a.size();    int n=b.size();    int len=dp[m-1][n-1];    string res(len,' ');    int count=0;    int i=m-1;    int j=n-1;    while(count<len)    {        if(i>0 && j>0 && dp[i][j]>dp[i-1][j] && dp[i][j]>dp[i][j-1])        {            res[len-1-count]=a[i];            count++;            i--;            j--;        }        else if(j>0 && dp[i][j]==dp[i][j-1])//向左        {            j--;        }        else if(i>0 && dp[i][j]==dp[i-1][j])//向上        {            i--;        }               if(count<len)        {            if(i==0)            {                res[0]=a[0];                count++;            }            else if(j==0)            {                res[0]=b[0];                count++;            }        }    }    return res;}int main(){    string a="A12C3D4B56";    string b="B1D23CA45B6A";    vector<vector<int>> dp;    dp=getdp(a,b);    string c=lcse(a,b,dp);    cout<<c<<endl;    return 0;}

3.最长公共子串

#include<iostream>#include<vector>#include<string>using namespace std;/*********************************///经典动态规划,时间复杂度m*n,空间复杂度m*nvector<vector<int>> getdp(string a,string b){    int m=a.size();    int n=b.size();    vector<vector<int>> dp(m,vector<int>(n));    dp[0][0]=a[0]==b[0]?1:0;    for(int i=1;i<m;i++)    {        dp[i][0]=a[i]==b[0]?1:0;    }    for(int j=1;j<n;j++)    {        dp[0][j]=a[0]==b[j]?1:0;    }    for(int i=1;i<m;i++)        for(int j=1;j<n;j++)        {            if(a[i]==b[j])              dp[i][j]=dp[i-1][j-1]+1;            else                dp[i][j]=0;        }        return dp;}string lcstl(string a,string b,vector<vector<int>> dp){    int m=a.size();    int n=b.size();    int l,k;    string res;    int max=dp[0][0];    for(int i=0;i<m;i++)        for(int j=0;j<n;j++)        {            if(dp[i][j]>max)            {                max=dp[i][j];                l=i;                k=j;            }        }        res=a.substr(l-max+1,max);    return res;}/*********************************///优化,时间复杂度m*n,空间复杂度o(1)string lcstl1(string a,string b){    int m=a.size();    int n=b.size();    int max=0;    int end;    int len=0;    string res;    int row=0;//开始行    int col=n-1;//开始列    while(row<m)    {        int i=row;        int j=col;        while(i<m && j<n)//一条斜线的循环        {            if(a[i]==b[j])                len++;            else                len=0;            if(len>max)            {                max=len;                end=i;            }            i++;            j++;        }        if(col>0)        {            col--;//斜线向左移        }        else         {            row++;//斜线        }    }    res=a.substr(end-max+1,max);    return res;}int main(){    string a="1AB2345CD";    string b="12345EF";    vector<vector<int>> dp;    dp=getdp(a,b);    int m=a.size();    int n=b.size();    for(int i=0;i<m;i++)    {        for(int j=0;j<n;j++)        {            cout<<dp[i][j]<<" ";        }        cout<<endl;    }    string c=lcstl(a,b,dp);    cout<<c<<endl;    string d=lcstl1(a,b);    cout<<d<<endl;    return 0;}