题目链接: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;
}
};