• (笔试题)删除K位数字


    题目:

    现有一个 n 位数,你需要删除其中的 k 位,请问如何删除才能使得剩下的数最大?

    比如当数为 2319274, k=1 时,删去 2 变成 319274 后是可能的最大值。

    思路:

    1、贪心算法

    每次从高位向低位数,删除高位数字比低位数字小的那位数字。如2319274

    第一次2<3,删除2,得到319274

    第二次3>1,略过,1<9,删除1,得到39274

    第三次3<9,删除3,得到9274

    。。。。。。

    // greedy method
    string deleteKBits_1(string str,int k){
        int tlen=str.length();
        bool flag=true;
        int len;
        while(k && flag){
            len=str.length();
            for(int i=0;i<len-1;i++){
                if(str[i]<str[i+1]){
                    str.erase(i,1);
                    flag=true;
                    break;
                }
            }
            k--;
        }
        return str.substr(0,tlen-k);
    }

    2、动态规划

    分析:

    假设str为长度为n的数字字符串,S[i][j]表示删除str[0...i-1]中j个数字后的最大字符数字。

    如果删除第i个数,则S[i][j]等于删除前i-1个字符中的j-1位的最优解,即S[i][j]=S[i-1][j-1];

    如果不删除第i个数,则S[i][j]等于删除前i-1个字符中j位的最优解+str[i],即S[i][j]=S[i-1][j]+str[i-1];

    即S[i][j]=max(S[i-1][j-1],S[i-1][j]+str[i-1])

    初始状态为当j=0时,不删除任何位的数字,即S[i][j]=str[0...i-1];

    状态转移方程如下:

    S[i][j]=

    strsub(0,i); (if j==0)

    max(S[i-1][j-1],S[i-1][j]+str[i-1]); (if 0<j<i;0<j<=k)

    时间复杂度:O(n*k)

    空间复杂度:O(n*k)

    优化:

    从上述的转移方程S[i][j]=max(S[i-1][j-1],S[i-1][j]+str[i-1]),可以看出在每一次i循环中,只与i-1相关,因此不需要用单独使用一个维度的数组来存储,只需要每次通过一个变量last保存上一次的结果。因此转移方程可以简化为S[j]=max(last,S[j]+str[i-1])

    时间复杂度:O(n*k)

    空间复杂度:O(k)

    // dynamic programming
    // time complexity: O(n*k)
    // space complexity: O(n*k)
    string deleteKBits_2(string str,int k){
        int tlen=str.length();
        vector<vector<string> > nums(tlen+1,vector<string>(k+1));
        string s1,s2;
        for(int i=1;i<=tlen;i++){
            for(int j=0;j<i && j<=k;j++){
                if(j==0){
                    nums[i][j]=str.substr(0,i);
                }
                else{
                    s1=nums[i-1][j-1];
                    s2=nums[i-1][j]+str[i-1];
                    if(s1.compare(s2)<=0)
                        nums[i][j]=s2;
                    else
                        nums[i][j]=s1;
                }
            }
        }
        return nums[tlen][k];
    }
    
    // dynamic programming
    // time complexity: O(n*k)
    // space complexity: O(k)
    string deleteKBits_3(string str,int k){
        int tlen=str.length();
        vector<string> nums(k+1);
        string s1,s2,last;
        for(int i=1;i<=tlen;i++){
            for(int j=0;j<i && j<=k;j++){
                if(j==0){
                    last=nums[j];
                    nums[j]=str.substr(0,i);
                }
                else{
                    // s1=last
                    s1=nums[j-1];
                    s2=nums[j]+str[i-1];
                    if(s1.compare(s2)<=0){
                        last=nums[j];
                        nums[j]=s2;
                    }
                    else{
                        last=nums[j];
                        nums[j]=s1;
                    }
                }
            }
        }
        return nums[k];
    }
    
    // dynamic programming
    // time complexity: O(n*k)
    // space complexity: O(k)
    string deleteKBits_4(string str,int k){
        int tlen=str.length();
        vector<string> nums(k+1);
        string tmp,s2,last;
        for(int i=1;i<=tlen;i++){
            for(int j=0;j<i && j<=k;j++){
                if(j==0){
                    last=nums[j];
                    nums[j]=str.substr(0,i);
                }
                else{
                    // s1=last
                    // s1=nums[j-1];
                    s2=nums[j]+str[i-1];
                    if(last.compare(s2)<=0){
                        last=nums[j];
                        nums[j]=s2;
                    }
                    else{
                        tmp=nums[j];
                        nums[j]=last;
                        last=tmp;
                    }
                }
            }
        }
        return nums[k];
    }
    

    运行结果:

    int main()
    {
        string str="2319274";
        int k=3;
        cout <<deleteKBits_1(str,k)<< endl;
        cout <<deleteKBits_2(str,k)<< endl;
        cout <<deleteKBits_3(str,k)<< endl;
        cout <<deleteKBits_4(str,k)<< endl;
        return 0;
    }
    

     

  • 相关阅读:
    BZOJ3631: [JLOI2014]松鼠的新家
    网络流24题题目总会+题解
    BZOJ3930: [CQOI2015]选数
    BZOJ4816: [Sdoi2017]数字表格
    Launcher类源码分析
    平台特定的启动类加载器深入分析与自定义系统类加载器详解
    类加载器命名空间总结与扩展类加载器要点分析
    类加载器命名空间深度解析与实例分析
    类加载器实战剖析与疑难点解析
    类加载器命名空间实战剖析与透彻理解
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4527382.html
Copyright © 2020-2023  润新知