T1: 设计一个 包含 取到min值函数 的 栈
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
解:
1.关键:
(1)借用 了 讨论区的 思想: 再存入 新的元素 x之前, 先把 前一个min_val 存到栈 里面 , 然后 更新min_val
(2)出栈 的时候 ,pop-> 更新 min_val ->pop
(3)直接返回min_val数据成员即可
2.代码:
class MinStack {
public:
//自己利用 而二进制序列定义 有符号 整数 最大值
const int MAX_INT = 0x7fffffff; //4个字节 , 8个十六进制数字
int min_val=MAX_INT; //这个就可以取到 整数的 最大值
stack St;
//妙啊, 借助 讨论区的 思想, 每次先存上一次的 最小值, 然后 再存 x
//每次pop ,都要pop两次
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
St.push(min_val);
//先加入 “上一次 最小值”
if(x < min_val)
{
min_val = x;
}
//入栈
St.push(x);
}
void pop() {
//出栈:
St.pop();
min_val = St.top(); // 更新 min_val
St.pop();
}
int top() {
return St.top();
}
int min() {
//反正不会 再 空栈的 时候调用
return min_val;
}
};
T2:用2个栈 实现 队列
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail
和 deleteHead
,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead
操作返回 -1 )
解:
1.关键:
(1)一个“输入栈” 一个“输出栈”
(2)入队 ,直接加入到 “输入栈”即可
(3)出队,如果“输出栈”还有元素 ,那就直接“输出栈”出栈即可, 否则 ,转存,然后stack2出栈
2.代码:
class CQueue {
public:
//最朴素的方法 就是 将stack1中的元素 倒序 存储到stack2中
//其实 就是 一个“输入栈” + 一个“输出栈”
//push都加入到stack1中 ,pop都从stack2中pop即可,nice
stack stack1;
stack stack2;
CQueue() {
}
void appendTail(int value) {
//加入一个 尾部元素 , 直接存储到 stack1中即可
stack1.push(value);
//删除元素的时候 才需要 将stack1 倒序存储到 stack2中
}
int deleteHead() {
//每次必须先把 之前的 stack2中的元素 全部删除才行
if(stack2.empty())
{
if(stack1.empty())
{
return -1;
}
else
{
put(); // 转存
}
}
int tmp =stack2.top();
stack2.pop();
return tmp;
}
void put()
{
while(!stack1.empty())
{
int tmp = stack1.top();
stack1.pop();
stack2.push(tmp);
}
}
};
T3:"三合一" 一个vector 作为 3个stack使用
三合一。描述如何只用一个数组来实现三个栈。
你应该实现push(stackNum, value)
、pop(stackNum)
、isEmpty(stackNum)
、peek(stackNum)
方法。stackNum
表示栈下标,value
表示压入的值。
构造函数会传入一个stackSize
参数,代表每个栈的大小。
解:
1.关键:
(1)主要是 处理 下标的 问题:
<1>每个stack的大小为size, 但是 这个vector分配了1+3*(size+1),也就是从1开始用,然后 每个stack有一个判断为空栈的不使用的位置
<2>栈空 坐标:index[stackNum] == stackNum*size+stackNum+1
<3>栈满 坐标:size+1 = (i+1)*size +(i+1)
2.代码:
class TripleInOne {
public:
//利用 一个 vec 实现 3个 stack ,主要是 处理下标的问题
vector vec;
int size=0;
//int index1=1,index2=0,index3=0; // 标记3个栈顶的 位置
int index[3];
TripleInOne(int stackSize) {
//构造函数
//每个栈的 大小 都是stackSize+1 , 空-第一个位置, 满-最后一个位置
vector tmp(3*(stackSize+1)+1,0); // 从下标1开始用
vec = tmp;
index[0] = 1; //栈 满 位置: size+1 = (i+1)*size +(i+1)
index[1] = stackSize+2; //满:2*size+2
index[2] = 2*stackSize+3; // 满 3*size+3
size = stackSize;
}
void push(int stackNum, int value) {
//(1)如果 栈满 不如栈:
if(index[stackNum] == (stackNum+1)*(size+1))
{
return ;
}
//入栈
index[stackNum]++;
vec[index[stackNum]] = value;
}
int pop(int stackNum) {
if(isEmpty(stackNum))
{
return -1;
}
int tmp = vec[index[stackNum]];
index[stackNum]--;
return tmp;
}
int peek(int stackNum) {
//返回栈顶 元素
if(isEmpty(stackNum))
{
return -1;
}
return vec[index[stackNum]];
}
bool isEmpty(int stackNum) {
//判断 栈 空:
if(index[stackNum] == stackNum*size+stackNum+1)
{
return true;
}
return false;
}
};
T4:递归实现汉诺塔问题(本质上是 栈结构)
在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制:
(1) 每次只能移动一个盘子;
(2) 盘子只能从柱子顶端滑出移到下一根柱子;
(3) 盘子只能叠在比它大的盘子上。
请编写程序,用栈将所有盘子从第一根柱子移到最后一根柱子。
你需要原地修改栈。
解:
1.关键:
(1)添加一个参数 n,表示要移动的 元素的个数
(2)注意,vec中 后面 指“上面”
(3)由于可以利用 pop_back() 和 back()函数 从后处理 vector,所以直接传递 vector的引用即可
2.代码:
class Solution {
public:
void hanota(vector& A, vector& B, vector& C) {
//其实 用递归写 这个函数 并不难 ,不过需要添加一个 参数n
int size= A.size();
move(size,A,B,C);
}
void move(int n ,vector& A,vector& B,vector& C)
{
//(1)出口
if(n==1)
{
//直接将A上的那个元素 移动到 C上即可
C.push_back(A.back());
A.pop_back();
return ;
}
//(2)递归:
//先借助C将n-1个元素 移动到 B
//然后 将 A最后一个元素移动到 C
//最后借助A将n-1的元素 从B移动到C
move(n-1,A,C,B);
C.push_back(A.back());
A.pop_back();
move(n-1,B,A,C);
}
};
T5:找出 二叉搜索树(BST)中的所有 众数
给你一个含重复值的二叉搜索树(BST)的根节点 root
,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。
如果树中有不止一个众数,可以按 任意顺序 返回。
假定 BST 满足如下定义:
解:
1.关键:
(1)必然需要遍历一次 所有的节点(就利用 先序遍历的 递归形式即可)
(2)再遍历的 同时 将 访问节点 改为 存储到Map中的 次数, 并且不断 更新当前的 做大出现次数max
(3)最后遍历一个Map找出所有 出现次数 == max的 元素
2.代码:
class Solution {
public:
unordered_map Map;
int max =0;
vector findMode(TreeNode* root) {
//(1)必然需要遍历一次
//(2)然后利用map 记录 每个数值出现的次数,并且记录当前最大次数 max
//(3)再遍历一个map,从而得到所以 出现次数 等于 max的数值
travel(root);
//利用 先序遍历, 递归形式
vector ans;
//遍历一次 map
for(auto &[v1,v2]: Map)
{
if(v2 == max)
{
ans.push_back(v1);
}
}
return ans;
}
void travel(TreeNode* root)
{
//(1)出口:
if(root == NULL)
{
return ;
}
//先访问该节点 , 加入到 map中 , 并且比较 max的数值
Map[root->val]++;
if(Map[root->val] > max)
{
max = Map[root->val];
}
//递归 ,先访问 左节点, 然后 访问 右节点
travel(root->left);
travel(root->right);
}
};
T6:填充 一个 完美二叉树的 节点的 “层序遍历 右侧 指针next”
给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node { int val; Node *left; Node *right; Node *next; }
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL
。
初始状态下,所有 next 指针都被设置为 NULL
。
解:
1.关键:
(1)由于 出队 和 入队的 关系容易混乱 ,这里 我才用 2个队列 交替使用, 一个队列负责 元素的 出队 ,同时 另一个队列 负责元素的 入队
(2)利用 bfs 广搜函数 和 update函数 :
<1>bfs 函数 : 负责 判断 2个队列 是否 同时 为空 -- 作为 结束点, 同时交替 叫用 update函数
<2>update函数: 负责 更新2个队列, 先从非空队列 中 取出元素 ,然后 将新的left , right节点 存到另一个队列中
2.代码:
class Solution {
public:
int flag=0;
Node* connect(Node* root) {
//bfs层序遍历 ,每个节点的 next指针 指向 这一层 右边的 节点
//而且这就是那个改进版本的 bfs 广搜,因为需要考虑每一层的最后一个节点的next
bfs(root);
return root;
}
void bfs(Node* root)
{
//创建2个队列 , 我记得 就是这样的,2个队列交替使用
//每次 访问完一个 队列的同时 ,把新的 节点元素 添加到 另外一个队列中
queue Que1;
queue Que2;
Que1.push(root);
while(!(Que1.empty() && Que2.empty()))
{
if(flag == 1)
{
return ;
}
//(1)Que1非空
if(!Que1.empty())
{
update(Que1,Que2);
}
//(2)Que2非空
else if(!Que2.empty())
{
update(Que2,Que1);
}
}
}
void update(queue& Q1 , queue& Q2)//取出Q1,存入Q2
{
Node* tmp = Q1.front();
if(tmp == NULL)
{
flag =1 ;
return ;
}
Q1.pop();
if(tmp->left!=NULL)
Q2.push(tmp->left);
if(tmp->right!=NULL)
Q2.push(tmp->right);
//负责 更新队列
while(!Q1.empty())
{
//从前 向后 依次 取出所有的节点
Node* node = Q1.front();
Q1.pop(); //出队
tmp->next = node;
tmp = node;
//同时 将 left 和 right节点 入队Q2
if(node->left !=NULL)
Q2.push(node->left);
if(node->right != NULL)
Q2.push(node->right);
}
if(tmp!=NULL)
{
tmp->next =NULL;
}
}
};
T7:将上面 那个题中的 “完全二叉树 ” 改为 “一般二叉树”
给定一个二叉树:
struct Node { int val; Node *left; Node *right; Node *next; }
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL
。
初始状态下,所有 next 指针都被设置为 NULL
。
解:
1.关键:
(1)上一题 可以利用 flag 只用 遇到 最后一层的 叶子节点 ,直接 return
(2)这里 考虑 ,把NULL 节点 出队 ,然后 “重进”
2.代码:
class Solution {
public:
Node* connect(Node* root) {
//bfs层序遍历 ,每个节点的 next指针 指向 这一层 右边的 节点
//而且这就是那个改进版本的 bfs 广搜,因为需要考虑每一层的最后一个节点的next
bfs(root);
return root;
}
void bfs(Node* root)
{
//创建2个队列 , 我记得 就是这样的,2个队列交替使用
//每次 访问完一个 队列的同时 ,把新的 节点元素 添加到 另外一个队列中
queue Que1;
queue Que2;
Que1.push(root);
while(!(Que1.empty() && Que2.empty()))
{
//(1)Que1非空
if(!Que1.empty())
{
update(Que1,Que2);
}
//(2)Que2非空
else if(!Que2.empty())
{
update(Que2,Que1);
}
}
}
void update(queue& Q1 , queue& Q2)//取出Q1,存入Q2
{
Node* tmp = Q1.front();
if(tmp == NULL)
{
Q1.pop();
return ;
}
Q1.pop();
if(tmp->left!=NULL)
Q2.push(tmp->left);
if(tmp->right!=NULL)
Q2.push(tmp->right);
//负责 更新队列
while(!Q1.empty())
{
//从前 向后 依次 取出所有的节点
Node* node = Q1.front();
Q1.pop(); //出队
tmp->next = node;
tmp = node;
//同时 将 left 和 right节点 入队Q2
if(node->left !=NULL)
Q2.push(node->left);
if(node->right != NULL)
Q2.push(node->right);
}
if(tmp!=NULL)
{
tmp->next =NULL;
}
}
};
T8:利用 stack栈 得到 按照 逆波兰顺序存储的 表达式的 结果
根据 逆波兰表示法,求该后缀表达式的计算结果。
有效的算符包括 +
、-
、*
、/
。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
解:
1.关键:
(1)利用 一个 stack 作为 工具
(2)遍历 vector ,分2种情况:
case1: 运算符 , 从stack中!!按次序 取出 num1 和 num2 ,注意 - 和 / 运算的次序,存入结果
case2: 整数, 直接存储到 stack中即可
2.代码:
class Solution {
public:
int evalRPN(vector& tokens) {
//利用 stack 栈实现 后缀 表达式 --逆波兰 表达式
//(1)如果 是一个 二元 运算符 , 就将stack中的 2个整数拿出来计算
//(2) 如果 不是二元 运算符 , 就把它存到栈里面
//(3)最后栈里面剩下的就是 最终结果
stack st;
//遍历依次 这个vec 利用 if进行相关的 判断
int size = tokens.size();
for(int i=0;i
T9:栈排序( “单调栈”)
栈排序。 编写程序,对栈进行排序使最小元素位于栈顶。最多只能使用一个其他的临时栈存放数据,但不得将元素复制到别的数据结构(如数组)中。该栈支持如下操作:push
、pop
、peek
和 isEmpty
。当栈为空时,peek
返回 -1。
解:
1.关键:
(1)主栈 中 始终 维持 有序的状态, 而 辅助栈 只是作为一个临时 存储的 容器
(2)再 push加入 新的 元素的 时候 ,其实 就好比 插入排序的 思想,: 找到 合适的为止,然后 再把那些 放到 辅助栈 中的元素 由 添加回来
2.代码:
class SortedStack {
public:
//这里好像一定 要对stack 进行排序 , 否则 每次pop会出问题
//这和 之前 做过的 一个 单调栈的 问题 好像是一样的
stack st1; // 主栈 : 里面的 元素都是排序的
stack st2; //辅助栈
SortedStack() {
}
void push(int val) {
//添加元素,直到 ,让 stack1一直出栈 , 然后 将元素 存到stack2中
while(!st1.empty() && (val > st1.top()))
{
//st1出栈 , st2 入栈
int tmp = st1.top();
st1.pop();
st2.push(tmp);
}
st1.push(val);
while(!st2.empty())
{
st1.push(st2.top());
st2.pop();
}
}
void pop() {
if(st1.empty())
{
return ;
}
st1.pop();
}
int peek() {
if(st1.empty())
{
return -1;
}
return st1.top();
}
bool isEmpty() {
return st1.empty();
}
};
T10:给定一个 入栈次序, 验证 这个出栈次序 是可能的
给定 pushed
和 popped
两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true
;否则,返回 false
。
解:
1.关键:
(1)模拟 这个出栈结果是否可能即可
(2) 以 遍历 popped序列:从前往后 遍历 , 每次 “不回头”地到 pushed序列中找
(3)如果 再 pushed序列中 找到了 ,删除这个元素, 并且 下标j--(j为0的时候除外),size1--,
2.代码:
class Solution {
public:
bool validateStackSequences(vector& pushed, vector& popped) {
// 这一题 也就是 说 :只要 这个pop的情况能够 实现就 true 否额则false上课题
//感觉有点 小难 ,也许 模拟可以做到
//果然 还是 模拟 一个 栈stack的 结构
//(1)主体 还是 遍历 数组 popped 从前往后 遍历,遇到了一个val
//然后:就可以对push从前往后遍历 去找那个val,找到了就出去
//之后:下一次 可以出栈的元素就是 val前一个元素 和 所有val后面的元素
int size1 = pushed.size();
int size2 = popped.size();
// j 不能回头
int j=0;
for(int i=0;i<=size2-1;i++)
{
int num = popped[i];
for( ;j <=size1-1;j++)
{
//是否可以 匹配:
if(pushed[j] == num)
{
//cout<size1-1 &&(pushed.size()))
{
return false;
}
}
return true;
}
};
T11:最大栈,既可以得到最大的元素,又可以让最大的元素出栈
设计一个最大栈数据结构,既支持栈操作,又支持查找栈中最大元素。
实现 MaxStack
类:
MaxStack()
初始化栈对象void push(int x)
将元素 x 压入栈中。int pop()
移除栈顶元素并返回这个元素。int top()
返回栈顶元素,无需移除。int peekMax()
检索并返回栈中最大元素,无需移除。int popMax()
检索并返回栈中最大元素,并将其移除。如果有多个最大元素,只要移除 最靠近栈顶 的那个。解:
1.关键:
(1)利用3个栈,一个普通栈存储原来的次序, 排序栈用来存储排序号的栈元素,辅助栈用来进行暂时存储的位置
2.代码:
第一次,最后三个 测试用例超时了, 我采用的是 普通栈 + 排序栈 + 辅助栈(3栈的思路进行代码的)
class MaxStack {
public:
//既然大家 都这么干, 那我就用 3栈 进行求解了
stack stack1; //这个栈中的元素都是按 顺序加入 栈中的
stack stack2; //这个栈中的元素都是 排序好的元素
stack stack3; //这个栈 是辅助栈,用来更新stack2的
//最后3个测试 用例超时了,真tm
MaxStack() {
}
void push(int x) {
stack1.push(x); //“真栈”中加入一个新的元素
//在stack2中找到合适的位置 并且 利用辅助栈(大的元素放到栈顶)
while((!stack2.empty()) && stack2.top()>x)
{
int top_num = stack2.top();
stack2.pop();
stack3.push(top_num);
}
stack2.push(x);
while(!stack3.empty())
{
int top_num = stack3.top();
stack3.pop();
stack2.push(top_num);
}
}
int pop() {
//stack1中直接移除栈顶元素
int top_num = stack1.top();
stack1.pop();
//stack2中,先利用辅助栈找到那个元素 , 然后再出栈
while(stack2.top() != top_num)
{
//--
int tmp = stack2.top();
stack2.pop();
stack3.push(tmp);
}
stack2.pop();
while(!stack3.empty())
{
int tmp = stack3.top();
stack3.pop();
stack2.push(tmp);
}
return top_num;
}
int top() {
//直接返回 栈顶元素
return stack1.top();
}
int peekMax() {
return stack2.top();
}
int popMax() {
//stack2直接移除最上面的那个元素即可
int top_num = stack2.top();
stack2.pop();
//stack1中:先找到top_num元素 , 然后移除
while(stack1.top() != top_num)
{
int tmp = stack1.top();
stack1.pop();
stack3.push(tmp);
}
stack1.pop();
while(!stack3.empty())
{
int tmp = stack3.top();
stack3.pop();
stack1.push(tmp);
}
return top_num;
}
};
借鉴了 评论区的 思想后,考虑 改用2个栈,一般栈 + 每次加入元素时的最大元素(打擂台的方法进行记录)
虽然还是 超时, 算了 ,有兴趣的 请去看 其它人的题解吧,难受得很
T12:最大频率栈
设计一个类似堆栈的数据结构,将元素推入堆栈,并从堆栈中弹出出现频率最高的元素。
实现 FreqStack
类:
FreqStack()
构造一个空的堆栈。void push(int val)
将一个整数 val
压入栈顶。int pop()
删除并返回堆栈中出现频率最高的元素。
解:
法一:(比较朴素 直接的 方法 -- 8个测试用例超时了--还是记录一下自己的思考历程)
1.关键:
(1)数据结构部分:
<1>stack1,就是一个 普通的栈结构
<2>map1 , 这个map的结构是
(2)入栈部分: stack1中直接入栈,而map1[val]++ , 即可
(3)出栈部分:先遍历map1,将所有出现次数最大的 元素 全部存储到 set1中,然后 从stack1的栈顶 依次 遍历,直到找到一个 元素 在set1中出现过为止 ,接着只要利用 辅助栈 ,将那个元素出栈即可,并且记得map[res]-- ,更新map
2.代码:
class FreqStack {
public:
//记录 栈中出现次数 最多的元素,并且每次 出栈都是 次数最多的元素出栈
//如果 次数相同,让接近栈顶的元素 出栈
//我打算,用一个map 记录 这一个pair
//可能需要利用map来 寻找那个出现频率最大的元素
map map1;//就用这种map吧,然后只要找到了,最先在stack中匹配的出栈
stack stack1;
FreqStack() {
}
void push(int val) {
stack1.push(val);
//--map1中对应元素出现的次数也要更新
map1[val]++;
}
int pop() {
//遍历map1,找出所有出现频率最高的map,然后,最先在stack中匹配的出栈
//并且更新map1[val] 出现的次数
int max=0;
unordered_set set1; //记录
for(auto [val,time]:map1)
{
if(time > max)
{
max = time; //说明最大的次数有变化
set1.clear();
set1.insert(val);
}
else if(time == max)
{
set1.insert(val);
}
}
//好了,现在出现次数 最多的 元素 都在set1中了
//从栈顶开始 遍历 这个栈
//利用辅助栈做好记录
stack stack2;
while(!set1.count(stack1.top()))
{
int tmp = stack1.top();
stack1.pop();
stack2.push(tmp);
}
int res = stack1.top();
stack1.pop();
while(!stack2.empty())
{
int tmp = stack2.top();
stack2.pop();
stack1.push(tmp);
}
//更新map
map1[res]--;
return res;
}
};
法二:利用2个map的数据结构进行求解 (这个是 借鉴答案的思想)
解:
1.关键:
(1)数据结构 map1:
map2
(2)一个精辟的评论:
//有一个问题:为什么不要考虑map[max_time-1]的这个 栈呢?
//妙处在于,一个数字xxx如果出现了5次,那么在频率1、频率2、……、频率5这五个栈里都有xxx
2.代码:
class FreqStack {
public:
//借鉴答案的思想, 多个栈 , 2个map
//map1:记录 从开始以来 所有的 栈中元素 次数
//map2:
T13:设计一个 支持 增量操作的 栈
请你设计一个支持对其元素进行增量操作的栈。
实现自定义栈类 CustomStack
:
CustomStack(int maxSize)
:用 maxSize
初始化对象,maxSize
是栈中最多能容纳的元素数量。void push(int x)
:如果栈还未增长到 maxSize
,就将 x
添加到栈顶。int pop()
:弹出栈顶元素,并返回栈顶的值,或栈为空时返回 -1 。void inc(int k, int val)
:栈底的 k
个元素的值都增加 val
。如果栈中元素总数小于 k
,则栈中的所有元素都增加 val
。解:
1.关键:
(1)利用 cnt 记录当前 栈 中的 元素 个数 , 利用 max记录 stack容器可以容纳的 最大元素个数
(2)pop 出栈函数的话, 直接出栈,然后更新cnt就好了
(3)inrement函数,将栈底的 k个 元素 +val , 利用 辅助栈 ,在入栈的时候 进行k次 +val的操作即可
2.代码:
class CustomStack {
public:
stack stack1;
int cnt=0;
int max=0;
CustomStack(int maxSize) {
max = maxSize;
cnt = 0 ; //记录当前栈中的元素 数量
}
void push(int x) {
//如果 已满,直接return
if(cnt == max)
{
return ;
}
else
{
stack1.push(x);
cnt++;
}
}
int pop() {
//出栈:
//(1)空栈
if(cnt == 0)
{
return -1;
}
//(2)
cnt--; //注意更新cnt 就好
int top_num = stack1.top();
stack1.pop(); // 原来忘记出栈
return top_num;
}
void increment(int k, int val) {
//前k个栈底 元素 增加val
//直接利用 辅助栈 进行操作即可
stack stack2;
//case1:cnt<=k , 所有元素增加val
while(!stack1.empty())
{
int tmp = stack1.top();
stack1.pop();
stack2.push(tmp);
}
int time=1;//总共k个元素即可
while(!stack2.empty())
{
int tmp = stack2.top(); //应该从栈底开始,这就是栈底啊
stack2.pop();
//进栈的时候有讲究
if(time <= k)
{
time++;
stack1.push(tmp+val);
}
else{
stack1.push(tmp);
}
}
//case2: 在进栈的时候进行加即可
}
};
T14:从 多个栈中 按照顺序取出 k个 硬币的 面值和最大
一张桌子上总共有 n
个硬币 栈 。每个栈有 正整数 个带面值的硬币。
每一次操作中,你可以从任意一个栈的 顶部 取出 1 个硬币,从栈中移除它,并放入你的钱包里。
给你一个列表 piles
,其中 piles[i]
是一个整数数组,分别表示第 i
个栈里 从顶到底 的硬币面值。同时给你一个正整数 k
,请你返回在 恰好 进行 k
次操作的前提下,你钱包里硬币面值之和 最大为多少 。
解:
扩展,由于需要用到 动态规划的 背包问题的内容这里 进行动态规划那本leetbook / 背包问题的学习
未完待续。。。