拼接最大数
给定长度分别为 m 和 n 的两个数组,其元素由 0-9 构成,表示两个自然数各位上的数字。现在从这两个数组中选出 k (k <= m + n) 个数字拼接成一个新的数,要求从同一个数组中取出的数字保持其在原数组中的相对顺序。
求满足该条件的最大数。结果返回一个表示该最大数的长度为 k 的数组。
说明: 请尽可能地优化你算法的时间和空间复杂度。
示例 1:
输入:
nums1 = [3, 4, 6, 5]
nums2 = [9, 1, 2, 5, 8, 3]
k = 5
输出:
[9, 8, 6, 5, 3]
示例 2:
输入:
nums1 = [6, 7]
nums2 = [6, 0, 4]
k = 5
输出:
[6, 7, 6, 0, 4]
示例 3:
输入:
nums1 = [3, 9]
nums2 = [8, 9]
k = 3
输出:
[9, 8, 9]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/create-maximum-number
思路总结
1.nums1中取m(0<=m<=k)个数,nums2中取n(0<=n<=k)个数,m+n=k;
取出所有的这种m和n的组合,放入 vector<vector>中。
2.遍历上述得出的组合结果,每次循环找到nums1中m的最大的数,nums2中找到n个最大的数
将这m和n的数组合成一个数组。
组合的方法是依次遍历找最大的插入
3.记录最大值即可;
参考答案
class Solution {
public:
std::vector<int> merge(const std::vector<int>& numb1, const std::vector<int>& numb2)
{
std::vector<int> result;
int i = 0;
int j = 0;
for(int r= 0; r < numb1.size()+ numb2.size(); r++) {
if(i==numb1.size()) {
result.push_back(numb2[j]);
j++;
continue;
}
if( j == numb2.size()) {
result.push_back(numb1[i]);
i++;
continue;
}
if(numb1[i] == numb2[j]) {
if(i==numb1.size()-1) {
result.push_back(numb2[j]);
j++;
continue;
}
if(j==numb2.size()-1) {
result.push_back(numb1[i]);
i++;
continue;
}
int m = i + 1, n = j + 1;
bool pushFlag = false;
while (m < numb1.size() && n < numb2.size()) {
if(numb1[m] > numb2[n]) {
result.push_back(numb1[i]);
i++;
pushFlag = true;
break;
}
if(numb1[m] < numb2[n]) {
result.push_back(numb2[j]);
j++;
pushFlag = true;
break;
}
m++;
n++;
}
if(!pushFlag) {
if(m == numb1.size()) {
result.push_back(numb2[j]);
j++;
continue;
}
if(n == numb2.size()) {
result.push_back(numb1[i]);
i++;
continue;
}
}else {
continue;
}
}
if(numb1[i] >numb2[j]) {
result.push_back(numb1[i]);
i++;
} else {
result.push_back(numb2[j]);
j++;
}
}
return result;
}
vector<int> getSerialMaxNumber(const std::vector<int>& nums, int n) {
stack<int> stackNums;
std::vector<int> result;
if (n == 0) {
return result;
}
stackNums.push(nums[0]);
for (int i = 1; i < nums.size(); i++) {
if (nums[i] > stackNums.top()) {
while (!stackNums.empty()) {
if (stackNums.size() + nums.size() - (i + 1) >= n) { //后面的元素个数充足,弹出顶部
if (nums[i] > stackNums.top()) {
stackNums.pop();
} else {
stackNums.push(nums[i]);
break;
}
} else { //后面的元素个数不足,直接插入
stackNums.push(nums[i]);
break;
}
}
if (stackNums.empty()) {
stackNums.push(nums[i]);
}
} else {
if (stackNums.size() < n) {
stackNums.push(nums[i]);
}
}
}
while (!stackNums.empty()) {
result.push_back(stackNums.top());
stackNums.pop();
}
std::reverse(result.begin(), result.end());
return result;
}
vector<vector<int>> getCombinations(int len1, int len2, int targetLen) {
vector<vector<int>> result;
if (len1 < 0 || len2 < 0 || targetLen < 0 || targetLen > len1 + len2) {
return result;
}
for (int i = 0; i <= len1; i++) {
if (targetLen - i >= 0 && targetLen - i <= len2) {
vector<int> temp;
temp.push_back(i);
temp.push_back(targetLen - i);
result.push_back(temp);
}
}
return result;
}
std::string vectorTostring(vector<int> numList)
{
std::string result="";
for (auto& item : numList)
{
result += std::to_string(item);
}
return result;
}
vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
//获得所有可能的 m+n
vector<vector<int>> combinations = getCombinations(nums1.size(), nums2.size(), k);
std::string max = "";
std::vector<int> finalyResult;
for (std::vector<int> vectorItem : combinations) {
//获得nums1中的最大m个数 nums2中的最大n个数
std::vector<int> newNums1 = getSerialMaxNumber(nums1, vectorItem[0]);
std::vector<int> newNums2 = getSerialMaxNumber(nums2, vectorItem[1]);
//将nums1中的最大m和nums2中的最大n个数,接接成最后的结果
std::vector<int> mergeResult = merge(newNums1, newNums2);
//找出最大的结果
if (vectorTostring(mergeResult) > max) {
max = vectorTostring(mergeResult);
finalyResult = mergeResult;
}
}
return finalyResult;
}
};