Leetcode-321. Create Maximum Number

广州已经入秋了,天气慢慢变冷,虽然冷得不是那么明显,所以还是经常刷刷题暖暖身吧!!废话不说,直接上题:

题目:

Given two arrays of length m and n with digits 0-9 representing two numbers. Create the maximum number of length k <= m + n from digits of the two. The relative order of the digits from the same array must be preserved. Return an array of the k digits. You should try to optimize your time and space complexity.

Example 1:

nums1 = [3, 4, 6, 5]
nums2 = [9, 1, 2, 5, 8, 3]
k = 5
return [9, 8, 6, 5, 3]

Example 2:

nums1 = [6, 7]
nums2 = [6, 0, 4]
k = 5
return [6, 7, 6, 0, 4]

Example 3:

nums1 = [3, 9]
nums2 = [8, 9]
k = 3
return [9, 8, 9]

Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.

Subscribe to see which companies asked this question


源码:

class Solution {
public:
	vector<vector<int>>get_max_number(vector<int>&nums){
		int size = nums.size();
		vector<vector<int>>n1(size + 1);
		vector<int>::iterator  j,k;
		//获取nums1每位最大的数
		bool flag = true;
		for (int i = size; i >= 1; i--){
			flag = true;
			if (i == size)n1[i] = nums;
			else{
				n1[i] = n1[i + 1];
				for (j = ++n1[i].begin(); j != n1[i].end(); j++){
					if (*j > *(j - 1)){
						j=n1[i].erase(j - 1);//清除前一位
						flag = false;
						break;
					}
				}
				if (flag){
					n1[i].pop_back();
				}
			}
		}
		return n1;
	}

	vector<int>merge(int n1, vector<int>&r1, int n2, vector<int>&r2){
		vector<int>re;
		int count1 = 0;
		int count2 = 0;
		while (count1 < n1&&count2 < n2){
			if (r1[count1] < r2[count2])re.push_back(r2[count2++]);
			else if (r1[count1] > r2[count2]) re.push_back(r1[count1++]);
			else{//如果两个数相等
				int s1 = count1, s2 = count2;
				while (s1 < n1&&s2 < n2&&r1[s1] == r2[s2]){//开始比较
					s1++;
					s2++;
				}
				if (s1 == n1 || (s2<n2&&r2[s2]>r1[s1]))re.push_back(r2[count2++]);
				else re.push_back(r1[count1++]);
			}
		}
		if (count1 == n1){//r1先结束
			for (int i = count2; i < n2; i++)re.push_back(r2[i]);
		}
		if (count2 == n2){//r1先结束
			for (int i = count1; i < n1; i++)re.push_back(r1[i]);
		}
		return re;
	}

	vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
		int size1 = nums1.size();
		int size2 = nums2.size();
		vector<vector<int>>r1, r2;
		r1 = get_max_number(nums1);
		r2 = get_max_number(nums2);
		vector<int>re;
		vector<int>total;
		if (size1 + size2 < k)return total;
		for (int i = 0; i <= k; i++){//取num1中的第i个数
			if (!(i <= size1&&k - i <= size2))continue;
			if (i == 0)re = r2[k - i];
			else re = merge(i, r1[i], k - i, r2[k - i]);
			if (total.size() == 0)total = re;
			else{
				for (int i = 0; i < k; i++){
					if (total[i] == re[i])continue;
					else if (total[i]>re[i])break;
					else total = re;
				}
			}
		}
		return total;
	}
};

运行结果:

Submission Result: Accepted  More Details 
Next challenges:  (M) Remove K Digits
Share your acceptance!

思路分析:

1. 首先解决在单个数组中,如何求出由n个数构成的最大值,这个时候利用动态规划思想

假设我们的数组元素有num={6,3,5,4,1,2},这时要求出n=6时数组元素所能构成的最大元素,则很明显是数组本身;

n=5时,我们要剔除1,则此时有{6,3,5,4,2}

n=4,有{6,3,5,4}

依次递归下去;求解的时候从第二个数开始,如果它比它前面的数大,则删除它前面的一个数;否则删除最后一个数;

2, 要求两个数组组成的最大的数,对于num1和num2来说,等于先从num1中选取i个数然后再从num2中选取k-i个数,然后按贪心原则分别从

这两个数组中取数!!!!


这里要十分注意的一点的是,我们在两个数组里分别取数遵循的原则不是取数字最大的i个数,而是能构成最大数值的i个数,假设:

我们在A数组中取的构成最大值的3个数是:{a1,a2,a3}

在数组B中,取得的构成的最大值的4个数是:{b1,b2,b3,b4}

那么对于A的三个数来说,无论B中的几个数如何插入到A中,{b1,b2,a1,b3,a2,b4,a3}在序列值固定的情况下,A中三个元素的贡献值为:a1*10000+a2*100*a3,如果

将a1,a2,a3中的任何一个值替换成A数组中其它的数,则其贡献值肯定减少!!!!所以一定是取能够成最大数值的i个数,而不是从左到右取最大的i个数字!!!!



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值