问题分析:

题目描述一大堆,实际上就是让你写大数加法,这就是一个脑筋急转弯。示例还特地不按数字大小排序的答案给出来,
就是怕你发现是找最大的x.size()-k+1个数字组成的最大数字
因为其他操作都是截取字符串,和求k-1个个位数的和。
最大和一定是最大的x.size.()-(k-1)个数字组成的数字和后面(k-1)每单个数字的和。
如何获取前x.size()-(k-1)个最大的数字且组合起来是最大的数字,只需要让字符串降序排列就行了,
然后调用一次substr,。接着计算后面(k-1)个数字的和与前面截取的字符串相加。因为字符串可能很长,
所以不能直接转数字相加,那么问题就变成了编写一个大数加法的问题。而因为题目已经限定了字符串最大长度。
所以后面(k-1)直接计算数字的和,最后转成字符串就行。
复杂度分析:
时间复杂度O(n):排序算法,库函数应该不会太大,截取子串单次操作,计算后k位和O(k),大数加法:O(max(k-1,x.size()-k+1))。
空间复杂度:O(n):取决于字符串大小和k的大小,主要是用于返回结果。
具体代码看下面:
class Solution {
public:
    static bool cmp(char &a,char &b){
        return a>b;
    } 
    string Maxsumforknumers(string x, int k) {
        if(k==1) return x;
        string res,tmp_str;
        int tmp=0;
        if(k==x.size()) {
            for(int i=0;i<x.size();++i) tmp+=x[i]-'0';
            res=to_string(tmp);
            return res;
        }
        sort(x.begin(),x.end(),cmp);
        res=x.substr(0,x.size()-k+1);
        for(int i=x.size()-k+1;i<x.size();++i) tmp+=x[i]-'0';
        tmp_str=to_string(tmp);
        res=sadds(res,tmp_str);
        return res;
    }
    string sadds(string res,string str2) {
        if(str2=="0") return res;
        if(res.size()<str2.size()) swap(res,str2);//保证res是最大长度的
        int k=0;//进位标志
        int x;//保存两个字符串每位相加的和,需加进位。从底到高
        int m=res.size()-1;
        int n=str2.size()-1;
        while(n>=0) {
            x=res[m]-'0'+str2[n]-'0'+k;
            res[m]=(x%10)+'0';
            k=x/10;
            --m,--n;
        }
        if(m==n&&k) {//当两个字符串长度相等时,需要考虑最后一次的进位
            res.insert(res.begin(),'1');
            return res;
        }
        while(m>=0&&k) {//较短字符串已经结束了,每次就看是否有进位
            x=res[m]-'0'+k;
            res[m]=(x%10)+'0';
            k=x/10;
            --m;
        }
        //如果上面一步一直到第一位,就需要看是否有进位
        if(m==-1&&k) res.insert(res.begin(),'1');
        return res;
    }
};