题目
作为一道hard题目的意思还是比较好理解的,而且可以推知需要使用单调栈; 题目提到要求取出的数字保持在原数组中的相对顺序,而且要求拼接的数最大,那么可以分解为分别求两个数组能获得的保持原相对顺序且应当是降序的序列!其实就是求两个数组的各自的单调栈(单调递减),但是要注意的是题目还有长度限制,这里是题目的难点!转题解中的一个图,要是能drop掉的数等于0了,那么后续的数应当直接填补上:
这里的drop_num等于数组长度减去要求的长度,表示的是按照递减条件能从单调栈pop出来的数的数量;
求单调栈的方法:
vector<int> GetMonStack(vector<int> &nums, int length){
stack<int> s;
int drop_num = nums.size() - length;
for(int i=0;i<nums.size();i++){
while(!s.empty() && s.top()<nums[i] && drop_num>0){
// 判断drop_num>0是关键点
s.pop();
drop_num--;
}
if(drop_num == 0){
// 要是drop_num == 0,那么后续的数字应当直接填补
while(i<nums.size()){
s.push(nums[i]);
i++;
}
break;
}
if(s.size()!=length)
s.push(nums[i]);
else
// 这个drop_num--是关键,要是因为已经满足要求长度而跳过的数字也应当进行drop_num--
drop_num--;
}
vector<int> res;
while(!s.empty()){
res.push_back(s.top());
s.pop();
}
reverse(res.begin(),res.end());
return res;
}
在两个数组各自的单调栈数组后对两者进行拼接,拼接的方法是:
(1)两两进行对比,选择大
(2)要是相同,那么对后一位进行比较,后一位大的胜出
vector<int> Merge(vector<int> &m1, vector<int> &m2){
int index1 = 0;
int index2 = 0;
vector<int> res;
while(index1<m1.size() && index2<m2.size()){
if(compare(m1,index1,m2,index2)>0)
res.push_back(m1[index1++]);
else
res.push_back(m2[index2++]);
}
while(index1<m1.size())
res.push_back(m1[index1++]);
while(index2<m2.size())
res.push_back(m2[index2++]);
return res;
}
int compare(vector<int> &m1, int index1, vector<int> &m2, int index2){
while(index1<m1.size() && index2<m2.size()){
int diff = m1[index1] - m2[index2];
if(diff!=0)
return diff;
index1++;
index2++;
}
if(index1<m1.size())
return 1;
else
return 0;
}
整体代码:
class Solution {
public:
vector<int> GetMonStack(vector<int> &nums, int length){
stack<int> s;
int drop_num = nums.size() - length;
for(int i=0;i<nums.size();i++){
while(!s.empty() && s.top()<nums[i] && drop_num>0){
s.pop();
drop_num--;
}
if(drop_num == 0){
while(i<nums.size()){
s.push(nums[i]);
i++;
}
break;
}
if(s.size()!=length)
s.push(nums[i]);
else
drop_num--;
}
vector<int> res;
while(!s.empty()){
res.push_back(s.top());
s.pop();
}
reverse(res.begin(),res.end());
return res;
}
vector<int> Merge(vector<int> &m1, vector<int> &m2){
int index1 = 0;
int index2 = 0;
vector<int> res;
while(index1<m1.size() && index2<m2.size()){
if(compare(m1,index1,m2,index2)>0)
res.push_back(m1[index1++]);
else
res.push_back(m2[index2++]);
}
while(index1<m1.size())
res.push_back(m1[index1++]);
while(index2<m2.size())
res.push_back(m2[index2++]);
return res;
}
int compare(vector<int> &m1, int index1, vector<int> &m2, int index2){
while(index1<m1.size() && index2<m2.size()){
int diff = m1[index1] - m2[index2];
if(diff!=0)
return diff;
index1++;
index2++;
}
if(index1<m1.size())
return 1;
else
return 0;
}
vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
int nums1_size = nums1.size();
int nums2_size = nums2.size();
int start = max(0,k-nums2_size);
int end = min(nums1_size,k);
cout<<start<<endl;
cout<<end<<endl;
vector<int> res;
for(int i = start;i<=end;i++){
vector<int> m1 = GetMonStack(nums1,i);
vector<int> m2 = GetMonStack(nums2,k-i);
res = max(Merge(m1,m2),res);
}
return res;
}
};