A 24 ms C++ solution with comments
// Get the max number from an array.\n    void getMax(int num,    // array.  Should have capacity >= len\n                int len,     // array length\n        
// Get the max number from an array.\n    void getMax(int* num,    // array.  Should have capacity >= len\n                int len,     // array length\n                int* result, // buffer for getting back the result.  Should have capacity >= t\n                int t)       // number of digit of the max number.  t <= len.\n    {\n        int n;\n        int top = 0;  // Take the result as a stack and this is the top index of the stack.  \n        \n        // Fill the first element\n        result[0] = num[0];\n        \n        for(int i = 1; i < len; ++i)\n        {\n            n = num[i];\n            // If top >= 0 AND result[top] is smaller than n AND there is enough remaining numbers to fill the result\n            while(top >= 0 && result[top] < n && (t - top) <= (len - i) )\n            {\n                // Pop the top element.\n                top--;\n            }\n            \n            // Move to the new top\n            top++;\n            if(top < t)\n                result[top] = n;\n            else\n               top = t - 1;  // stay at the last element.\n        }\n    }\n    \n    // Merge two numbers so they generate the max number.  This merge runs in linear time O(m + n)\n    void merge(int* num1,    // num1 with length of len1\n               int len1, \n               int* num2,    // num2 with length of len2\n               int len2, \n               int* result)  // result with length of (len1 + len2)\n    {\n        int i;\n        int j, k;\n        int t = len1 + len2;\n        for(i = 0, j = 0, k = 0; i < t; ++i)\n        {\n            if(j < len1 && k < len2)\n            {\n                // Pick the larger number\n                if(num1[j] > num2[k])\n                    result[i] = num1[j++];\n                else if(num1[j] < num2[k])\n                    result[i] = num2[k++];\n                else // if equal\n                {\n                    int remaining1 = len1 - j;\n                    int remaining2 = len2 - k;\n                    if(remaining1 > remaining2)\n                    {\n                        // Compare remaining part.  Pick the larger one.\n                        if(memcmp(num1 + j, num2 + k, sizeof(int) * remaining2) >= 0)\n                            result[i] = num1[j++];\n                        else\n                            result[i] = num2[k++];\n                    }\n                    else\n                    {\n                        if(memcmp(num2 + k, num1 + j, sizeof(int) * remaining1) >= 0)\n                            result[i] = num2[k++];\n                        else\n                            result[i] = num1[j++];\n                    }\n                }\n            }\n            else if(j < len1 && k >= len2)\n            {\n                // Keep adding the remaining numbers\n                result[i] = num1[j++];\n            }\n            else // if(j >= len1 && k < len2)\n            {\n                // Keep adding the remaining numbers\n                result[i] = num2[k++];\n            }\n        }\n    }\n    \n    vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {\n        \n        // Allocate memory\n        int* num = new int[k * 4];\n        int* buf1 = num + k;\n        int* buf2 = num + k * 2;\n        int* temp = num + k * 3;\n        int memSize = sizeof(int) * k;\n        memset(num, 0, memSize);\n        \n        int i;\n        int t1, t2;\n        int len1 = nums1.size();\n        int len2 = nums2.size();\n        if(len1 == 0 && len2 > 0)\n        {\n            getMax(&nums2[0], len2, num, k);\n        }\n        else if(len1 > 0 && len2 == 0)\n        {\n            getMax(&nums1[0], len1, num, k);\n        }\n        else if(len1 > 0 && len2 > 0)\n        {\n            if(len1 <= len2)\n            {\n                int smaller = len1 < k ? len1 : k;\n                for(i = k - len2; i <= smaller; ++i)\n                {\n                    // Tranverse the numbers with all possible combinations\n                    t1 = i;\n                    t2 = k - i;\n                    getMax(&nums1[0], len1, buf1, t1);\n                    getMax(&nums2[0], len2, buf2, t2);\n                    merge(buf1, t1, buf2, t2, temp);\n                    if(memcmp(num, temp, memSize) < 0)\n                        memcpy(num, temp, memSize);\n                }\n            }\n            else\n            {\n                int smaller = len2 < k ? len2 : k;\n                for(i = k - len1; i <= smaller; ++i)\n                {\n                    // Tranverse the numbers with all possible combinations\n                    t2 = i;\n                    t1 = k - i;\n                    getMax(&nums1[0], len1, buf1, t1);\n                    getMax(&nums2[0], len2, buf2, t2);\n                    merge(buf1, t1, buf2, t2, temp);\n                    if(memcmp(num, temp, memSize) < 0)\n                        memcpy(num, temp, memSize);\n                }\n            }\n        }\n        \n        vector<int> rev(num, num + k);\n        delete [] num;\n        \n        return rev;\n\n    }
[]