Leetcode-321. Create Maximum Number

来源:互联网 发布:mac下载铃声 编辑:程序博客网 时间:2024/05/17 01:13

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

题目:

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