LeetCode 321 Create Maximum Number

给定两个数组,要求用这些数字组成一个长度为k的最大的数字,要求两个数组内的数字顺序不变。

枚举两个数组各处多少个数字,第一个数组出i个,第二个数组就出k-i个,然后取出的这两个数字本身就要最大。因为如果不是最大,那我换成最大的填到最终的数字中一定更大。

单个数组求去掉一定数字能得到的最大数字比较简单,用一个栈来维护,只要还能删掉数字并且准备入栈的数字比栈顶数字要大,那就将栈顶数字出栈。

两个数组的最大数字求得后,只需要用归并操作将两个数字合并就可以,不过要注意的是,如果两个队列顶的数字相同时,需要比较两个剩下的数组谁比较大,将较大的那个队列头归并。

C++ Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
class Solution {
public:
vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
int sz1 = nums1.size();
int sz2 = nums2.size();
vector<int> ret;
for(int i = max(0, k - sz2); i <= min(k, sz1); ++i) {
ret = max(ret, mergeVec(maxVec(nums1, sz1 - i), maxVec(nums2, sz2 - (k - i))));
}
return ret;
}

vector<int> maxVec(vector<int> &nums, int drop) {
vector<int> ret;
for(int i = 0; i < nums.size(); ++i) {
while(!ret.empty() && drop > 0 && ret.back() < nums[i]) {
ret.pop_back();
--drop;
}
ret.push_back(nums[i]);
}
while(drop > 0) {
ret.pop_back();
--drop;
}
return ret;
}

vector<int> mergeVec(const vector<int> &v1, const vector<int> &v2) {
vector<int> ret;
int sz1 = v1.size();
int sz2 = v2.size();
int pos1 = 0, pos2 = 0;
while(pos1 < sz1 || pos2 < sz2) {
if(pos2 == sz2) {
ret.push_back(v1[pos1++]);
}else if(pos1 == sz1) {
ret.push_back(v2[pos2++]);
}else if(v1[pos1] < v2[pos2]) {
ret.push_back(v2[pos2++]);
}else if(v1[pos1] > v2[pos2]) {
ret.push_back(v1[pos1++]);
}else {
ret.push_back(v1[pos1]);
compare(v1, v2, pos1, pos2)? ++pos1: ++pos2;
}
}
return ret;
}

bool compare(const vector<int> &v1, const vector<int> &v2, int pos1, int pos2) {
for(int i = pos1, j = pos2; ;++i, ++j) {
if(i == v1.size()) {
return false;
}else if(j == v2.size()) {
return true;
}else if(v1[i] < v2[j]) {
return false;
}else if(v1[i] > v2[j]) {
return true;
}
}
return false;
}
};