Solution
C++ []\nclass Solution {\npublic:\n    #define MIN(a,b) (a<b?a:b)\n    #define MAX(a,b) (a>b?a:b)\n    void getMax(int* num, int& len, int* result, int& t, int&
```C++ []\nclass Solution {\npublic:\n    #define MIN(a,b) (a<b?a:b)\n    #define MAX(a,b) (a>b?a:b)\n    void getMax(int* num, int& len, int* result, int& t, int& sortedLen)\n    {\n    \tint n, top = 0;\n    \tresult[0] = num[0];\n    \tconst int need2drop = len - t;\n    \tfor (int i = 1; i < len; ++i){\n    \t\tn = num[i];\n    \t\twhile (top >= 0 && result[top] < n && (i - top) <= need2drop) --top;\n    \t\tif (i - top > need2drop){\n    \t\t\tsortedLen = MAX(1,top);\n    \t\t\twhile (++top < t) result[top] = num[i++];\n    \t\t\treturn;\n    \t\t}\n    \t\tif (++top < t) result[top] = n;\n    \t\telse top = t - 1;\n    \t}\n    }\n    void dp(int *num, int len, int&sortedLen, int& minL, int& maxL, int *res, int &k){\n    \tint  j, *head, *prevhead = res;\n    \tconst int soi = sizeof(int);\n    \tgetMax(num, len, res, maxL,sortedLen);\n    \tfor (int l = maxL; l > MAX(minL,1); --l){\n    \t\thead = prevhead + k;\n    \t\tmemcpy(head, prevhead, l*soi);\n    \t\tfor (j = sortedLen; j < l; ++j){\n    \t\t\tif (head[j] > head[j - 1]){\n    \t\t\t\tsortedLen = MAX(1, j - 1);\n    \t\t\t\tmemcpy(head + j - 1, prevhead + j, soi*(l - j));\n    \t\t\t\tbreak;\n    \t\t\t}\n    \t\t}\n    \t\tif (j == l) sortedLen = l;\n    \t\tprevhead = head;\n    \t}\n    }\n    void merge(int* num1,int len1,int* num2,int len2,int* result,int& resSize){\n    \tint i = 0, j = 0, k = 0;\n    \twhile (i < resSize){\n    \t\tif (j < len1 && k < len2){\n    \t\t\tif (num1[j] > num2[k])\n    \t\t\t\tresult[i++] = num1[j++];\n    \t\t\telse if (num1[j] < num2[k])\n    \t\t\t\tresult[i++] = num2[k++];\n    \t\t\telse{\n    \t\t\t\tint remaining1 = len1 - j, remaining2 = len2 - k, tmp = num1[j];\n    \t\t\t\tint flag = memcmp(num1 + j, num2 + k, sizeof(int) * MIN(remaining1, remaining2));\n    \t\t\t\tflag = (flag == 0 ? (remaining1>remaining2 ? 1 : -1) : flag);\n    \t\t\t\tint * num = flag > 0 ? num1 : num2;\n    \t\t\t\tint & cnt = flag > 0 ? j : k;\n    \t\t\t\tint len = flag > 0 ? len1 : len2;\n    \t\t\t\twhile (num[cnt]==tmp && cnt < len && i<resSize) result[i++] = num[cnt++];\n    \t\t\t}\n    \t\t}\n    \t\telse if (j < len1) result[i++] = num1[j++];\n    \t\telse result[i++] = num2[k++];\n    \t}\n    }\n    vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k){\n    \tint soi = sizeof(int), len1 = nums1.size(), len2 = nums2.size(), step = k*soi;\n    \tint minL1 = MAX(0, k - len2), maxL1 = MIN(k, len1), minL2 = k - maxL1, maxL2 = k - minL1, range = maxL1 - minL1 + 1;\n    \tint * res = new int[range * k * 2 + 2 * k], *dp1 = res + k, *dp2 = res + range*k+k, *tmp=res+range*2*k+k;\n    \tmemset(res, 0, step);\n    \tint sortedLen1 = 1, sortedLen2 = 1;\n    \tif (len1 == 0 && len2 > 0) getMax(&nums2[0], len2, res, k, sortedLen2);\n    \telse if (len1 > 0 && len2 == 0) getMax(&nums1[0], len1, res, k, sortedLen2);\n    \telse if (len1 > 0 && len2 > 0){\n    \t\tdp(&nums1[0], len1, sortedLen1, minL1, maxL1, dp1,k);\n    \t\tdp(&nums2[0], len2, sortedLen2, minL2, maxL2, dp2,k);\n    \t\tif (sortedLen1 + sortedLen2 > k){\n    \t\t\tmerge(dp1 + k*(maxL1 - sortedLen1), sortedLen1, dp2 + k*(maxL2 - sortedLen2), sortedLen2, tmp, k);\n    \t\t\tvector<int> resv(tmp, tmp + k);\n    \t\t\tdelete[] res;\n    \t\t\treturn resv;\n    \t\t}\n    \t\tfor (int i = minL1; i <= maxL1; ++i){\n    \t\t\tmerge(dp1+k*(maxL1-i), i, dp2+k*(maxL2-k+i), (k-i), tmp,k);\n    \t\t\tif (memcmp(res, tmp, step) < 0) memcpy(res, tmp, step);\n    \t\t}\n    \t}\n    \tvector<int> resv(res, res + k);\n    \tdelete[] res;\n    \treturn resv;\n    }\n};\n```\n\n```Python3 []\nclass Solution:\n    def maxNumber(self, nums1: List[int], nums2: List[int], k: int) -> List[int]:\n            \n        def get_max_subarray(nums, k):\n            stack = []\n            drop = len(nums) - k\n            for num in nums:\n                while drop and stack and stack[-1] < num:\n                    stack.pop()\n                    drop -= 1\n                stack.append(num)\n            return stack[:k]\n\n        max_num = []\n\n        for i in range(max(0, k - len(nums2)), min(k, len(nums1)) + 1):\n            max_subarray1 = get_max_subarray(nums1, i)\n            max_subarray2 = get_max_subarray(nums2, k - i)\n\n            candidate = []\n            while max_subarray1 or max_subarray2:\n                if max_subarray1 > max_subarray2:\n                    candidate.append(max_subarray1.pop(0))\n                else:\n                    candidate.append(max_subarray2.pop(0))\n\n            if candidate > max_num:\n                max_num = candidate\n\n        return max_num\n```\n\n```Java []\nclass Solution {\n    public int[] maxNumber(int[] nums1, int[] nums2, int k) {\n\n    int m = nums1.length, n = nums2.length;\n    int[] ans = new int[k];\n    \n    for (int i = Math.max(0, k-n); i <= Math.min(k, m); i++) {\n        int j = k - i;\n        int[] maxNum1 = getMax(nums1, i);\n        int[] maxNum2 = getMax(nums2, j);\n        int[] merged = merge(maxNum1, maxNum2);\n        if (compare(merged, 0, ans, 0) > 0) {\n            ans = merged;\n        }\n    }\n    return ans;\n}\nprivate int[] getMax(int[] nums, int k) {\n    int n = nums.length;\n    int[] stack = new int[k];\n    int top = -1, remaining = n - k;\n    \n    for (int i = 0; i < n; i++) {\n        int num = nums[i];\n        while (top >= 0 && stack[top] < num && remaining > 0) {\n            top--;\n            remaining--;\n        }\n        if (top < k - 1) {\n            stack[++top] = num;\n        } else {\n            remaining--;\n        }\n    }\n    return stack;\n}\nprivate int[] merge(int[] nums1, int[] nums2) {\n    int m = nums1.length, n = nums2.length;\n    int[] merged = new int[m + n];\n    int i = 0, j = 0, k = 0;\n    \n    while (i < m && j < n) {\n        if (compare(nums1, i, nums2, j) > 0) {\n            merged[k++] = nums1[i++];\n        } else {\n            merged[k++] = nums2[j++];\n        }\n    }\n    while (i < m) {\n        merged[k++] = nums1[i++];\n    }\n    while (j < n) {\n        merged[k++] = nums2[j++];\n    }\n    return merged;\n}\nprivate int compare(int[] nums1, int i, int[] nums2, int j) {\n    int m = nums1.length, n = nums2.length;\n    while (i < m && j < n) {\n        int diff = nums1[i] - nums2[j];\n        if (diff != 0) {\n            return diff;\n        }\n        i++;\n        j++;\n    }\n    return (m - i) - (n - j);\n}\n}\n```\n
['C++', 'Java', 'Python3']