力扣练习——28 拼接最大数

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;

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值