力扣练习——28 拼接最大数
作者:互联网
1.问题描述
给定长度分别为 m 和 n 的两个数组,其元素由 0-9 构成,表示两个自然数各位上的数字。现在从这两个数组中选出 k (k <= m + n) 个数字拼接成一个新的数,要求从同一个数组中取出的数字保持其在原数组中的相对顺序。
求满足该条件的最大数。结果返回一个表示该最大数的长度为 k 的数组。
说明: 请尽可能地优化你算法的时间和空间复杂度。
示例 1:
输入:
nums1 = [3, 4, 6, 5]
nums2 = [9, 1, 2, 5, 8, 3]
k = 5
输出:
[9, 8, 6, 5, 3]
示例 2:
输入:
nums1 = [6, 7]
nums2 = [6, 0, 4]
k = 5
输出:
[6, 7, 6, 0, 4]
示例 3:
输入:
nums1 = [3, 9]
nums2 = [8, 9]
k = 3
输出:
[9, 8, 9]
可使用以下main函数:
int main()
{
int m,n,k,data;
vector<int> nums1,nums2;
cin>>m;
for(int i=0; i<m; i++)
{
cin>>data;
nums1.push_back(data);
}
cin>>n;
for(int i=0; i<n; i++)
{
cin>>data;
nums2.push_back(data);
}
cin>>k;
vector<int> res=Solution().maxNumber(nums1,nums2,k);
for(int i=0; i<res.size(); i++)
cout<<res[i];
return 0;
}
2.输入说明
首先输入数组长度m,然后输入m个0-9的数字,各数字以空格分隔。
然后输入数组长度n,然后输入n个0-9的数字,各数字以空格分隔。
最后输入整数k。
3.输出说明
输出结果数组,输出内容无空格。
4.范例
输入
2
6 7
3
6 0 4
5
输出
67604
5.代码
#include<iostream> #include<vector> #include<string> #include<algorithm> #include<unordered_map> #include<set> #include<stack> using namespace std; int compare(vector<int>&nums1, int index1, vector<int>&nums2, int index2); //1.求单调栈 vector<int> GetMonStack(vector<int> &nums, int len) { stack<int>s;//定义结果栈s int n = nums.size(); int drop_num = n - len;//需要去除的元素个数 //遍历nums数组,进行单调栈的构造,求最大值 for (int i = 0; i < n; i++) { while (!s.empty() && s.top() < nums[i] && drop_num > 0)//栈非空且栈顶元素值比目前遍历到的nums[i]小,且需要舍弃的个数还没达到时,舍弃栈顶元素 { s.pop(); drop_num--; } if (s.size() < len)//注意入栈前判断是否已满 { s.push(nums[i]);//入栈操作 } else//和前面入栈相反,元素被舍弃 { drop_num--; } } //将栈s中元素转为vector类型 vector<int>res(len,0); int i = len - 1; while (!s.empty()) { res[i--] = s.top(); s.pop(); } return res; } //2.单调栈v1,v2合并操作 vector<int> MergeVector(vector<int> &v1, vector<int> &v2) { //1.计算大小并判断特殊值 int size_v1 = v1.size(); int size_v2 = v2.size(); if (!size_v1)//v1为空 return v2; if (!size_v2)//v2为空 return v1; //2.逐个比较最大值 int index1, index2; index1 = index2 = 0; int i = 0; int length = size_v1 + size_v2; vector<int>res(length,0);//定义结果数组 //比较返回更大值 while (i < length) { if (compare(v1, index1, v2, index2) > 0) { res[i++] = v1[index1++]; } else res[i++] = v2[index2++]; } return res; } int compare(vector<int>&nums1, int index1, vector<int>&nums2, int index2) { int x = nums1.size(); int y = nums2.size(); while (index1 < x && index2 < y)//都没遍历完 { int tag = nums1[index1++] - nums2[index2++]; if (tag != 0) return tag; } return (x - index1) - (y - index2);//有一个已经遍历完 } vector<int> maxNumber(vector<int>&nums1, vector<int>&nums2, int k) { int size_1 = nums1.size(); int size_2 = nums2.size(); //start和end分别代表构造的v1单调栈的长度最小值和最大值 int start = max(0, k - size_2); //理解下?若要取的个数K>v2.size() ,说明v1至少要取k-v2.size()个数,才能凑够K个数 int end = min(k, size_1);//若K<size_1() ,则最多从v1中取出k个数 vector<int>res(k, 0);//结果数组 for (int i = start; i <= end; i++) { vector<int> v1(GetMonStack(nums1, i)); vector<int> v2(GetMonStack(nums2, k - i)); vector<int> tmp(MergeVector(v1, v2)); if (compare(tmp, 0, res, 0) > 0) res.swap(tmp);//注意这里swap()的妙用 ,实时更新res到最大值 } return res; } int main() { int m, n, k, data; vector<int> nums1, nums2; cin >> m; for (int i = 0; i < m; i++) { cin >> data; nums1.push_back(data); } cin >> n; for (int i = 0; i < n; i++) { cin >> data; nums2.push_back(data); } cin >> k; vector<int> res = maxNumber(nums1, nums2, k); for (int i = 0; i < res.size(); i++) cout << res[i]; return 0; }
标签:最大数,int,28,力扣,v2,vector,nums1,nums2,size 来源: https://www.cnblogs.com/juillard/p/16489643.html