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.

Note: You should try to optimize your time and space complexity.

Example 1:

Input:
nums1 = [3, 4, 6, 5]
nums2 = [9, 1, 2, 5, 8, 3]
k = 5
Output:
[9, 8, 6, 5, 3]

Example 2:

Input:
nums1 = [6, 7]
nums2 = [6, 0, 4]
k = 5
Output:
[6, 7, 6, 0, 4]

Example 3:

Input:
nums1 = [3, 9]
nums2 = [8, 9]
k = 3
Output:
[9, 8, 9]

There may be some excellent solutions, but I just think of a sample solution using greedy and pass through.
We need to get a number with k’s length from two vectors, then we have the following situations:
gain 0 number from nums1, k numbers from nums2;
gain 1 number from nums1, k - 1 numbers from nums2;

gain k numbers from nums1, 0 number from nums2.
And we should consider the size of vector to judge whether we can get enough numbers from it.
For gettting maximum number, each number we extract from nums1 and nums2 should be the maximum too, that’s what the function maxVector does, then we merge the two number from nums1 and nums2 into one number while make sure the consequence number is biggest. We compare among all the possible combinations, choose the biggest one, and that’ what we want.

class Solution {
public:
    bool greaterVector(vector<int>& nums1, int nums1_start, vector<int>& nums2, int nums2_start)
    {
        //We compare nums1(nums1.begin() + nums1_start, nums1.end()) with nums2(nums2.begin() + nums2_start, nums2.end()).
        //The way to compare two vector is exactly same as the way to compare two strings.
        //If nums1[nums1_start] == nums2[nums2_start], then compare the next elememts of nums1 and nums2.
        while (nums1_start < nums1.size() && nums2_start < nums2.size() && nums1[nums1_start] == nums2[nums2_start]) { nums1_start++; nums2_start++; };
        //The reason that jumping the while code segment belongs to the set:
        //-- nums1_start == nums1.size()
        //-- nums2_start == nums2.size()
        //nums1[nums1_start] != nums2[nums2_start]
        return (nums2_start == nums2.size() || (nums1_start < nums1.size() && nums1[nums1_start] > nums2[nums2_start]));
    }
    vector<int> maxVector(vector<int>& nums, int k)
    {
        if (k == 0)return {};
        //The variable result is the vector for result.
        vector<int> result(k, INT_MIN);
        //We should go through the nums for get the result. In order to ensure the result right, we should fill it as the following way.
        //Let us suppose we haven't gone through the nums, and we are on the index i currently, and we have fill j numbers into the result.
        //Apparently, the number of the elements we have passed is nums.size() - i, and if (nums.size() - i) <= (k - j), then we have no choice but fill the result by the other elements which have a bigger index greater than i.
        //In the situation we have enough choices, if nums[i] > result[j - 1], the we substitute result[j - 1] with nums[i], it's because we will get a bigger vector by doing that.
        int j = 0;
        for (int i = 0; i < nums.size(); i++)
        {
            while ((nums.size()) - i >(k - j) && j > 0 && nums[i] > result[j - 1])j--;
            if (j < k)result[j++] = nums[i];
        }
        return result;
    }
    vector<int> mergeVector(vector<int>& nums1, vector<int>& nums2)
    {
        int i = 0, j = 0, k = 0;
        vector<int> result(nums1.size() + nums2.size(), 0);
        while (i < nums1.size() && j < nums2.size())
        {
            if (nums1[i] > nums2[j]) { result[k++] = nums1[i++]; }
            else if (nums1[i] < nums2[j]) { result[k++] = nums2[j++]; }
            else
            {
                //Let us consider the situation if nums1[i] == nums2[j], we choose the first letter of the bigger vector between nums1(nums1.begin() + i, nums1.end()) and nums2(nums2.begin() + j, nums2.end())
                //For example, the left parts of nums1 and nums2 are "06132" and "05322", which should we choose, the former or the latter?
                //The consequence of chossing the latter vector is that we will get "056..." which is not the best answer.
                if (greaterVector(nums1, i, nums2, j))result[k++] = nums1[i++];
                else result[k++] = nums2[j++];
            }
        }
        if (i >= nums1.size())while (j < nums2.size())result[k++] = nums2[j++];
        if (j >= nums2.size())while (i < nums1.size())result[k++] = nums1[i++];
        return result;
    }
    vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k)
    {
        //m, n is the nums1's and mums2's size respectively.
        int m = nums1.size();
        int n = nums2.size();
        //The variable biggest is aimed to store the biggest result we will get at every step.
        vector<int> biggest;
        //Firstly, we assume that all elememts of nums1 are included into the result,
        //then there are max(0, k - m) elements of which belong to nums2 in the result.
        //In the following loop, variable i represents the number of nums2's element which are put into the result.
        //The variable i varies in the range from max(0, k - m) to min(n, k).
        for (int i = (0 < (k - m) ? (k - m) : 0); i <= (n < k ? n : k); i++)
        {
            //Because there are i elements of nums2 which are put into the result, at least (k - i) nums1's elements must be counted.
            //We want to get a biggest number vector, so it's appropriate goal for us to get two number vectors from nums1 and nums2 whose size are (k - i) or i respectively.
            //Then we merge these two number vector, and compare it with thr biggest number vector we have got, update the variable used to store the biggest number vector alternatively.
            vector<int> maxvector1 = maxVector(nums1, k - i);
            vector<int> maxvector2 = maxVector(nums2, i);
            vector<int> curvector = mergeVector(maxvector1, maxvector2);
            if (greaterVector(curvector, 0, biggest, 0))biggest = curvector;
        }
        return biggest;
    }
};

www.sunshangyu.top

猜你喜欢

转载自blog.csdn.net/qq_34229391/article/details/82287331