leetcode-321. Create Maximum Number-hard

来源:互联网 发布:一台机器多个ip linux 编辑:程序博客网 时间:2024/04/30 23:04

题目链接:https://leetcode.com/problems/create-maximum-number/#/description

这道题好难,我是看了discuss之后自己写出来的,用到了map存储, dp的思想,存储已经算出来的结果,以后用的时候没必要再算;还用到了贪心,具体体现在计算map和merge的函数中。

本题思路:

  • 首先先从两个nums数组中分别计算从长度为i到k的最长数字组合,存储到map < int, vector < int > >中, 当然,其中的索引必须小于k和nums.size()。
  • 然后,分别从这两个map中寻找匹配起来长度为k的vector,然后将它们merge。
  • merge也用到了贪心,如果首个数字不相同还好说,把大的取出来;但是,如果首字母相同,就得往后比较,取出后面比较大的那个vector < int>的首字母;
  • 在此过程中维护一个最大的结果。

经验:

  • vector中reserve函数是申请空间,emplace函数是往里插,erase函数才是去除元素。

我的C++代码:

class Solution {public:    map<int, vector<int>> find(vector<int> nums, int k) {        map<int, vector<int>> ret;        for (int i=nums.size(); i>=0; i--) {                //cout<<nums.size()<<"i"<<i<<endl;                if (i == 0) {                    nums.clear();                   // cout<<"i = 0 size: "<<nums.size()<<endl;                }            if (i <= k) {                ret[i] = nums;            }            for (int j = 0; j<i-1; j++) {                if (i == 1) {                    nums.clear();                    //cout<<"have clear:"<<nums.size()<<endl;                    break;                } else if (nums[j] < nums[j+1]) {                    nums.erase(nums.begin()+j);                    break;                } else if (j == i-2) {                    nums.erase(nums.begin()+j+1);                    break;                }            }        }        return ret;    }    vector<int> merge(map<int, vector<int> > &map1,  map<int, vector<int> > &map2, int i, int j) {        vector<int> ret;        if (map1.find(i) == map1.end() || map2.find(j) == map2.end()) {            return ret;        }        vector<int> temp1 = map1[i];        vector<int> temp2 = map2[j];        while (!temp1.empty() || !temp2.empty()) {            if (!temp1.empty() && !temp2.empty()) {                if (temp1[0] > temp2[0]) {                    ret.push_back(temp1[0]);                    temp1.erase(temp1.begin()+0);                } else if (temp1[0] < temp2[0]){                    ret.push_back(temp2[0]);                    temp2.erase(temp2.begin()+0);                } else {                    int next1=temp1[0],next2=temp2[0];                    int ii=1, jj=1, flag = 1;                    while (next1 == next2) {                        if (temp1.size()==ii && temp2.size()==jj)                            break;                        if (temp1.size()==ii){                            next1 = 0;                        } else {                            next1 = temp1[ii];                            ii++;                        }                        if (temp2.size() == jj) {                            next2 = 0;                        } else {                            next2 = temp2[jj];                            jj++;                        }                    }                    if (next1 > next2) {                        ret.push_back(temp1[0]);                        temp1.erase(temp1.begin());                    } else {                        ret.push_back(temp2[0]);                        temp2.erase(temp2.begin());                    }                }            } else if (!temp1.empty()) {                while (!temp1.empty()) {                    ret.push_back(temp1[0]);                    temp1.erase(temp1.begin()+0);                }            } else {                while (!temp2.empty()) {                    ret.push_back(temp2[0]);                    temp2.erase(temp2.begin()+0);                }            }        }        return ret;    }    bool isBigger(vector<int> & cur, vector<int> &temp) {        if (temp.size() > cur.size()) {            return true;        }        for (int i=0; i<cur.size(); i++) {            if (cur[i] > temp[i]) {                return false;            } else if (cur[i] < temp[i]) {                return true;            }        }        return false;    }    vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {        vector<int> ret;        map<int, vector<int> > map1;        map<int, vector<int> > map2;        map1 = find(nums1, k);        map2 = find(nums2, k);        vector<int> cur;        for (int i=0; i<=k; i++) {            vector<int> temp = merge(map1,map2,i, k-i);            if (temp.size() == 0)                continue;            if (isBigger(cur, temp)) {                cur = temp;            }        }        ret = cur;        return ret;    }};
1 0