当前位置:网站首页>leetcode:321. 拼接最大数
leetcode:321. 拼接最大数
2022-08-09 22:01:00 【OceanStar的学习笔记】
题目来源
题目描述
class Solution {
public:
vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
}
};
题目解析
题意
这道题给了我们两个数组,里面的数字是无序的,又给我们一个k值并且k <= n1 + n2,要求我们从两个数组中跳出k个数,数字之间的相对顺序不变,求能组成的最大的数
单调栈
为什么可以使用单调栈?
- 本题的本质即为从两个数组中挑选k个元素,并且使得拼接后的字典序最大。
- 要使得数组的字典序最大,则需要保证从左到右的每一个位置的值尽可能的大,即单调递减
思路:
- 可以枚举所有k的组合情况,分别从两个数组中取i、j个元素构成的最大数组,然后再进行合并,最终保留最大值
- 在挑选指定个数的元素的过程中,分别从两个数组中取i、j个元素构成的最大数组,然后再进行合并,最终保留最大值
问题: 枚举所有k的组合情况?
由于k的大小不定,所以有三种可能:
- 第一种是当k为0时,两个数组中都不取数。
- 第二种是当k不大于其中任意一个数组的长度时,这种情况下,有可能只从一个数组中取数,或者两个都取一些。
- 第三种情况是k大于其中任意一个数组的长度,则需要从两个数组中分别取数,至于每个数组中取几个,每种情况都要考虑到,然后每次更结果即可。
为了同时能处理这三种情况,这里假设从数组 nums1 中取i个数,那么就需要从 nums2 中取 k-i 个数。那么i的范围如何确定呢?
- 怎么确定i的起始范围?
- 由情况二的得出:可以不从nums1中取数,所以i最小值为0
- 由情况三的得出:假如所有数均从nums2中取&&k > len(nums2),那么剩下的k - size2数必须从nums1取。
- 综上,i的起始范围为std::max(0, k - size2)
- 怎么确定i的结束范围?也就是i最大能多大
- 如果k <= size1,那么最大能从nums1中取k个
- 如果k > size1,那么最大能从nums1中取size1个
- 综上,i的结束范围为std::min(k, size1);
怎么一个数组挑选出最大的组合?
- 比如当前数组长度为n,需要取出k个数字,那么需要对掉drop = n - k个数字
- 遍历数组中的数字,进行如下循环: 如果此时drop > 0 && ans不为空 && ans.back < curr,那么丢弃ans并drop-+ 重复循环直至上述任意条件不满足为止,然后把当前元素加入结果数组中
- 最后返回ans数组中的前k个元素
现在分别从 nums1 中取出了i个最大组合的数字,从 nums2 中取出了 k-i 个最大组合的数字,怎么合并呢?
- 先比较两个元素中首部元素大小
- 然后从当前比较大的数组中取头一个元素
- 然后删除头部元素
- …接着比较,直到两个数组都为空停止
class Solution {
std::vector<int> mergeVector(vector<int>& nums1, vector<int>& nums2){
std::vector<int> ans;
while (!nums1.empty() || !nums2.empty()){
vector<int> &tmp =(nums1 > nums2) ? nums1 : nums2;
ans.push_back(tmp[0]);
tmp.erase(tmp.begin());
}
return ans;
}
// 从nums中挑选k个数
std::vector<int> maxVector(vector<int>& nums, int k){
int drop = (int) nums.size() - k;
std::vector<int> ans;
for(int num : nums){
while (drop > 0 && !ans.empty() && ans.back() < num){
ans.pop_back();
--drop;
}
ans.push_back(num);
}
ans.resize(k);
return ans;
}
public:
vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
int size1 = nums1.size(), size2 = nums2.size();
std::vector<int> ans;
int start = std::max(0, k - size2);
int end = std::min(k, size1);
for (int i = start; i <= end; ++i) {
// 最多可以从nums1中选end个数
auto pick1 = maxVector(nums1, i);
auto pick2 = maxVector(nums2, k - i);
ans = std::max(ans, mergeVector(pick1, pick2));
}
return ans;
}
};
int main() {
vector<int> nums1 {
3, 4, 6, 5};
vector<int> nums2 {
9, 1, 2, 5, 8, 3};
Solution a;
auto ans = a.maxNumber(nums1, nums2, 5);
for(auto i : ans){
printf("%d\t", i);
}
return 0;
}
类似题目
- 316. 去除重复字母
- 402. 移掉 K 位数字
- 核心思路与402. 移掉 K 位数字一样,使用单调栈获取最大数字。
- 不一样的是,402题是一个数组,且要移除的次数确定,321题是「两个数组」,移除的次数「不确定」
- Maximum Swap 最大置换
边栏推荐
- 力扣 1413. 逐步求和得到正数的最小值
- typedef和#define的花里胡哨的用法
- This article lets you quickly understand implicit type conversion [integral promotion]!
- 你的 Link Button 能让用户选择新页面打开吗?
- Socket发送缓冲区接收缓冲区快问快答
- JuiceFS 在多云存储架构中的应用 | 深势科技分享
- Deceptive Dice
- Xiaohei's leetcode journey: 94. Inorder traversal of binary trees (supplementary Morris inorder traversal)
- 级联下拉菜单的实现「建议收藏」
- 【微服务~Nacos】Nacos之配置中心
猜你喜欢
从产品角度看 L2 应用:为什么说这是一个游乐场?
孙正义亏掉1500亿:当初投贵了
Analyze the Add() method in Fragment management from the source code
FileZilla搭建FTP服务器图解教程
abstract class or interface
Five Star Holdings Wang Jianguo: Deepen the track with "plant spirit" and promote growth with "animal spirit"
Chatting embarrassing scenes, have you encountered it?Teach you to get the Doutu emoticon package with one click, and become a chat expert
[Cloud Native] 4.2 DevOps Lectures
电脑系统重装后怎么用打印机扫描出文件?
leetcode 刷题日记 计算右侧小于当前元素的个数
随机推荐
Presto Event Listener开发
Xiaohei's leetcode journey: 94. Inorder traversal of binary trees (supplementary Morris inorder traversal)
【微服务~Nacos】Nacos之配置中心
华为鸿蒙3.0的野望:技术、应用、生态
腾讯继续挥舞降本增效“大刀”,外包员工免费餐饮福利被砍了
Basic JSON usage
十步以内,用小程序快速生成App!
Space not freed after TRUNCATE table
Leetcode.25 K个一组翻转链表(模拟/递归)
第 1 章 一大波数正在靠近——排序
Install win virtual machine on VMware
Converting angles to radians
重要的不是成为海贼王,而是像路飞一样去冒险
js array object deduplication
编译原理之文法
shell学习
NodeJS使用JWT
JS Deobfuscation - AST Restoration Case
charts.js插件实现的散点图样式
R语言检验时间序列的平稳性:使用tseries包的adf.test函数实现增强的Dickey-Fuller(ADF)检验、检验时序数据是否具有均值回归特性(平稳性)、不具有均值回归特性的案例