Open azl397985856 opened 5 months ago
class CustomStack {
public:
int ssize;
stack<int> ss;
CustomStack(int maxSize) {
ssize = maxSize;
}
void push(int x) {
if (ss.size() < ssize) ss.push(x);
}
int pop() {
if(!ss.empty()) {
int res = ss.top();
ss.pop();
return res;
}
else return -1;
}
void increment(int k, int val) {
stack<int> ss2;
while (!ss.empty()){
ss2.push(ss.top());
ss.pop();
}
int sum = 0;
while(!ss2.empty()){
sum++;
if (sum <= k) ss.push(ss2.top() + val);
else ss.push(ss2.top());
ss2.pop();
}
}
};
思路:
代码:
class CustomStack {
public:
vector<int> stk, add;
int top;
CustomStack(int maxSize) {
stk.resize(maxSize);
add.resize(maxSize);
top = -1; //没满栈,监测栈顶位置
}
void push(int x) {
if(top != stk.size()-1){ //错误 if(top < stk.size()-1)
++top;
stk[top] = x;
// std::cout << 'test';
}
// std::cout << top <<'\n';
}
int pop() {
int cur;
if(top==-1) return -1; //空了
cur = stk[top] + add[top];
if(top != 0) add[top-1] += add[top]; // 错误 add[top-1] = add[top]
add[top] = 0; //跟着元素出栈清零
--top;
return cur;
}
void increment(int k, int val) {
int rag;
rag = min(k, top+1);
// 优化器前
// for(int i = 0; i<rag; ++i){
// stk[i] += val;
// }
if( rag >= 1) add[rag-1] += val;
}
};
复杂度:
Java 思路: 底层创建一个数组用于存储数据,并定义一个变量保存数组中的有效元素个数
class CustomStack {
private int[] a;// 底层数组 保存数据
private int N;// 数组逻辑长度
public CustomStack(int maxSize) {// maxSize>=1
a = new int[maxSize];
}
public void push(int x) {
if (N == a.length)
return;
a[N++] = x;
}
public int pop() {
if (N == 0)
return -1;
return a[--N];
}
public void increment(int k, int val) {// k>=1
if (k >= N) {
for (int i = 0; i < N; i++) {
a[i] += val;
}
} else {
for (int i = 0; i < k; i++) {
a[i] += val;
}
}
}
}
/**
* @param {number} maxSize
*/
var CustomStack = function(maxSize) {
this.maxSize = maxSize;
this.stack = [];
};
/**
* @param {number} x
* @return {void}
*/
CustomStack.prototype.push = function(x) {
if(this.stack.length === this.maxSize) return;
this.stack.push(x);
};
/**
* @return {number}
*/
CustomStack.prototype.pop = function() {
if(this.stack.length === 0) return -1;
return this.stack.pop();
};
/**
* @param {number} k
* @param {number} val
* @return {void}
*/
CustomStack.prototype.increment = function(k, val) {
console.log(k, this.stack)
for (let i=0; i < k; i++) {
if(i < this.stack.length) {
this.stack[i] += val
}
}
};
time complexity: push: O(1) pop: O(1) increment O(k) space complexity: O(n) n = maxSize
额外创建一个数组int[] inc来记录对应的index上增加的值,index = Math.min(k, stack.size()) - 1。 当pop操作时,将pop出的值与inc[i]的值相加返回,inc[i-1]的值要加上inc[i]的值,之后inc[i]变为0.
class CustomStack {
int n;
int[] inc;
Stack
public CustomStack(int maxSize) {
n = maxSize;
inc = new int[n];
stack = new Stack<>();
}
public void push(int x) {
if(stack.size() < n) {
stack.push(x);
}
}
public int pop() {
int i = stack.size() - 1;
if(i < 0) {
return -1;
}
if(i > 0) {
inc[i - 1] += inc[i];
}
int res = stack.pop() + inc[i];
inc[i] = 0;
return res;
}
public void increment(int k, int val) {
int i = Math.min(k, stack.size()) - 1;
if(i >= 0) {
inc[i] += val;
}
}
}
**复杂度分析**
- 时间复杂度:所有操作均为O(1)
- 空间复杂度:开了新的数组所以为O(N)
class CustomStack:
def __init__(self, maxSize: int):
self.maxSize = maxSize
self.stack = []
def push(self, x: int) -> None:
if len(self.stack) < self.maxSize:
self.stack.append(x)
def pop(self) -> int:
if self.stack:
return self.stack.pop()
else:
return -1
def increment(self, k: int, val: int) -> None:
for i in range(min(k, len(self.stack))):
self.stack[i] += val
Cool. 时隔半年再做, 终于可以很快做出来了.
class CustomStack:
def __init__(self, maxSize: int):
self.maxSize = maxSize
self.array = []
def push(self, x: int) -> None:
if len(self.array) < self.maxSize:
self.array.append(x)
def pop(self) -> int:
if len(self.array) == 0:
return -1
else:
return self.array.pop()
def increment(self, k: int, val: int) -> None:
for i in range(min(k, len(self.array))):
self.array[i] += val
# Your CustomStack object will be instantiated and called as such:
# obj = CustomStack(maxSize)
# obj.push(x)
# param_2 = obj.pop()
# obj.increment(k,val)
class CustomStack:
def __init__(self, maxSize: int):
self.stack = []
self.size = 0
self.maxSize = maxSize
self.add = []
def push(self, x: int) -> None:
if self.size < self.maxSize:
self.stack.append(x)
self.size += 1
self.add.append(0)
def pop(self) -> int:
if self.size > 0:
self.size -= 1
inc = self.add.pop()
if self.size > 0:
self.add[-1] += inc
val = self.stack.pop()
return val+inc
return -1
def increment(self, k: int, val: int) -> None:
n = min(k, self.size)
if n >= 1:
self.add[n-1] += val
time: push O(1), pop O(1), increment O(1), space O(N)
/**
* @param {number} maxSize
*/
var CustomStack = function(maxSize) {
this.stack = []
this.length = maxSize
};
/**
* @param {number} x
* @return {void}
*/
CustomStack.prototype.push = function(x) {
if(this.stack.length !== this.length){
this.stack.push(x);
}
};
/**
* @return {number}
*/
CustomStack.prototype.pop = function() {
if(this.stack.length === 0) return -1
return this.stack.pop();
};
/**
* @param {number} k
* @param {number} val
* @return {void}
*/
CustomStack.prototype.increment = function(k, val) {
const l = k > this.stack.length ? this.stack.length : k
for(let i = 0; i < l; i++) {
this.stack[i] += val
}
};
时间复杂度:push、pop O(1) increment O(n) 空间复杂度:push、pop O(1) increment O(n)
可以借助数组数据结构模拟栈,进栈调用 push
API,出栈调用 pop
API。进栈的时候判断数组长度是不是大于 maxSize, 出栈的时候判断数组长度是否为 0
/**
* @param {number} maxSize
*/
var CustomStack = function (maxSize) {
this.maxSize = maxSize;
this.stack = [];
};
/**
* @param {number} x
* @return {void}
*/
CustomStack.prototype.push = function (x) {
if (this.stack.length < this.maxSize) {
this.stack.push(x);
}
return null;
};
/**
* @return {number}
*/
CustomStack.prototype.pop = function () {
if (this.stack.length > 0) {
return this.stack.pop();
}
return -1;
};
/**
* @param {number} k
* @param {number} val
* @return {void}
*/
CustomStack.prototype.increment = function (k, val) {
var temp = [];
for (let i = 0; i < k; i++) {
if (this.stack.length > 0) {
temp.push(this.stack.shift());
}
}
while (temp.length > 0) {
const v = temp.pop();
this.stack.unshift(v + val);
}
return null;
};
...
复杂度分析
通过数组来模拟栈。通过push和pop来操作栈。CustomStack有两个属性一个是list,一个是maxSize; increment的实现: 遍历长度判断 const len = this.list.length > k ? k : this.list.length; 如果栈长度大于k,那么就遍历到k,如果长度小于k,那么遍历整个list即可;
/*
* @lc app=leetcode.cn id=1381 lang=javascript
*
* [1381] 设计一个支持增量操作的栈
*/
// @lc code=start
/**
* @param {number} maxSize
*/
var CustomStack = function (maxSize) {
const list = [];
// list.length = maxSize;
this.maxSize = maxSize;
this.list = list;
};
/**
* @param {number} x
* @return {void}
*/
CustomStack.prototype.push = function (x) {
if (this.list.length >= this.maxSize) {
return;
}
this.list.push(x);
};
/**
* @return {number}
*/
CustomStack.prototype.pop = function () {
if (this.list.length <= 0) {
return -1;
}
return this.list.pop();
};
/**
* @param {number} k
* @param {number} val
* @return {void}
*/
CustomStack.prototype.increment = function (k, val) {
const len = this.list.length > k ? k : this.list.length;
for (let i = 0; i < len; i++) {
this.list[i] += val;
}
};
/**
* Your CustomStack object will be instantiated and called as such:
* var obj = new CustomStack(maxSize)
* obj.push(x)
* var param_2 = obj.pop()
* obj.increment(k,val)
*/
// @lc code=end
时间复杂度:
class CustomStack {
constructor(maxSize) {
this.maxSize = maxSize;
}
/**
* 最大值
* @param {number} maxSize
*/
maxSize = 0;
/**
* 栈空间
*/
stack = [];
/**
* 初始化
* @param {number} maxSize
*/
/**
* 入栈
* @param {number} maxSize
* @return {void}
*/
push(x) {
if (this.stack.length < this.maxSize) this.stack.push(x);
return null;
}
/**
* 出栈
* @param {number} x
* @return {number}
*/
pop(x) {
if (this.stack.length > 0) return this.stack.pop();
return -1;
}
/**
* 增加值操作
* @param {number} k
* @param {number} val
*/
increment(k, val) {
for (let i = 0; i < k && i < this.stack.length; i++) {
this.stack[i] += val;
}
return null;
}
}
// 输入:
const action = ['CustomStack', 'push', 'push', 'pop', 'push', 'push', 'push', 'increment', 'increment', 'pop', 'pop', 'pop', 'pop'];
const param = [[3], [1], [2], [], [2], [3], [4], [5, 100], [2, 100], [], [], [], []];
const run = (action, param) => {
let stack = null;
let result = [];
let res = null;
action.map((a, i) => {
if (a === 'CustomStack') {
stack = new CustomStack(...param[i]);
res = null;
} else {
res = stack[a](...param[i]);
}
result.push(res);
});
return result;
};
console.log(run(action, param));
时间复杂度: push、pop: O(1) increment:O(k) 空间复杂度:O(maxsize)
(1)使用vector容器作为数据的载体 (2)vector的末尾作为栈顶
class CustomStack {
private:
int _size;
int _maxsize;
vector<int> stack;
public:
CustomStack(int maxSize) {
_maxsize=maxSize;
_size=0;
}
void push(int x) {
if(_size < _maxsize)
{
stack.push_back(x);
_size++;
}
}
int pop() {
if(0 == stack.size())
return -1;
int re = stack.back();
stack.pop_back();
_size--;
return re;
}
void increment(int k, int val) {
if(k > stack.size())
k=stack.size();
int count=0;
for(auto it = stack.begin(); it != stack.end(); ++it)
{
if(count == k)
break;
*it += val;
count++;
}
}
};
复杂度分析: CustomStack(int maxSize):
void push(int x):
int pop():
void increment(int k, int val):
数组实现栈
class CustomStack {
// 声明一个数组,作为自定义栈的底层实现
int[] stackArray;
// 栈顶位置监控
int pos = 0;
public CustomStack(int maxSize) {
stackArray = new int[maxSize];
}
public void push(int x) {
// 栈空间满了,不能入栈
if(pos==stackArray.length){
return;
}
// 入栈
stackArray[pos++]=x;
}
public int pop() {
if(pos==0){
return -1;
}
return stackArray[--pos];
}
public void increment(int k, int val) {
// 栈中元素个数小于k
if(k>stackArray.length){
for(int i = 0;i<stackArray.length;i++){
stackArray[i] += val;
}
} else{
// 栈中元素个数小于k
for(int j =0;j<k;j++){
stackArray[j] += val;
}
}
}
}
时间复杂度: push、pop: O(1),increment:O(K) 空间复杂度:O(maxSize)
补打卡 class CustomStack { // 1。 直接使用双栈比较直接,就是保存一个元素总和,当递增的时候用备用栈倒出来,从倒到n-k的时候开始增加,然后再倒回去原来的栈
// 2。 其实这道题考察的是模拟的思想,用数组表示栈,会更直接一点,每次incre就遍历0-k对数组执行++就行,这样incre的复杂度是Ok
// 3。 有一个比较巧妙的方法就是使用前缀和数组的思想,用数组实现栈,保存一个addArr[i]表示在i位置需增加的值,这样每次increment只用增加addArr[k]位置的值
// push保存一个栈顶索引,topIndex,pop的时候需要拿到stack[topIndex]+addArr[topIndex]的值
// 又因为每次incre的时候只是增加了addArr[k],为了保证每次取到的值都是已经被加过的,所以每次pop以后,addArr[topIndex-1]位置也要增加addArr[topIndex]
// 这样看似有点难理解,但是想清楚了就很妙了,可以保证incre的时候复杂度都是O1
int [] stack;
int addArr[];
int topIndex;
// 直接写一下前缀和方式
public CustomStack(int maxSize) {
addArr = new int[maxSize];
stack = new int[maxSize];
topIndex = -1;
}
public void push(int x) {
if(topIndex == stack.length-1){
return ;
}
stack[++topIndex] = x;
}
public int pop() {
if(topIndex==-1){
return -1;
}
int addVal = addArr[topIndex];
int res = stack[topIndex]+addVal;
// 更新最新top索引处的add值
if(topIndex>=1){
addArr[topIndex-1] += addVal;
}
// 记得还原addArr[topIndex] =0
addArr[topIndex] =0;
topIndex--;
return res;
}
public void increment(int k, int val) {
// 这里要用topIndex和K比较
int actualK = Math.min(k,topIndex+1);
if(actualK >=1){
addArr[actualK-1] +=val;
}
}
}
/**
}
class CustomStack {
protected:
vector<int> m_customStack;
int m_pos = -1;
int m_maxSize = 1;
public:
CustomStack(int maxSize):m_customStack(maxSize),m_maxSize(maxSize) {
}
void push(int x) {
if(m_pos < m_maxSize - 1){
m_pos ++;
m_customStack[m_pos] = x;
}
}
int pop() {
if(m_pos == -1){
return -1;
}
m_pos --;
return m_customStack[m_pos + 1];
}
void increment(int k, int val) {
int increNum = 0;
if(m_pos + 1 < k ){
increNum = m_pos + 1;
}else{
increNum = k;
}
for(int i = 0;i < increNum;i++){
m_customStack[i] += val;
}
}
};
class CustomStack {
private maxSize: number;
private stack: number[];
private incMap: any;
constructor(maxSize) {
this.maxSize = maxSize;
this.stack = [];
this.incMap = {}; // 用于记录增量操作
}
push(x) {
if (this.stack.length < this.maxSize) {
this.stack.push(x);
}
}
pop() {
if (this.stack.length === 0) {
return -1;
}
// 处理增量操作
let inc = this.incMap[this.stack.length] || 0;
if (this.stack.length > 1) {
this.incMap[this.stack.length - 1] = (this.incMap[this.stack.length - 1] || 0) + inc;
}
return this.stack.pop() + inc;
}
increment(k, val) {
const top = Math.min(k, this.stack.length);
this.incMap[top] = (this.incMap[top] || 0) + val;
}
}
用数组模拟栈
var CustomStack = function(maxSize) { this.stack = []; this.maxSize = maxSize };
/**
/**
@return {number} */ CustomStack.prototype.pop = function() { if (this.stack.length === 0) { return -1 }
return this.stack.pop() };
/**
1381. 设计一个支持增量操作的栈
入选理由
暂无
题目地址
https://leetcode-cn.com/problems/design-a-stack-with-increment-operation/
前置知识
题目描述
实现自定义栈类 CustomStack :
CustomStack(int maxSize):用 maxSize 初始化对象,maxSize 是栈中最多能容纳的元素数量,栈在增长到 maxSize 之后则不支持 push 操作。 void push(int x):如果栈还未增长到 maxSize ,就将 x 添加到栈顶。 int pop():弹出栈顶元素,并返回栈顶的值,或栈为空时返回 -1 。 void inc(int k, int val):栈底的 k 个元素的值都增加 val 。如果栈中元素总数小于 k ,则栈中的所有元素都增加 val 。
示例:
输入: ["CustomStack","push","push","pop","push","push","push","increment","increment","pop","pop","pop","pop"] [[3],[1],[2],[],[2],[3],[4],[5,100],[2,100],[],[],[],[]] 输出: [null,null,null,2,null,null,null,null,null,103,202,201,-1] 解释: CustomStack customStack = new CustomStack(3); // 栈是空的 [] customStack.push(1); // 栈变为 [1] customStack.push(2); // 栈变为 [1, 2] customStack.pop(); // 返回 2 --> 返回栈顶值 2,栈变为 [1] customStack.push(2); // 栈变为 [1, 2] customStack.push(3); // 栈变为 [1, 2, 3] customStack.push(4); // 栈仍然是 [1, 2, 3],不能添加其他元素使栈大小变为 4 customStack.increment(5, 100); // 栈变为 [101, 102, 103] customStack.increment(2, 100); // 栈变为 [201, 202, 103] customStack.pop(); // 返回 103 --> 返回栈顶值 103,栈变为 [201, 202] customStack.pop(); // 返回 202 --> 返回栈顶值 202,栈变为 [201] customStack.pop(); // 返回 201 --> 返回栈顶值 201,栈变为 [] customStack.pop(); // 返回 -1 --> 栈为空,返回 -1
提示:
1 <= maxSize <= 1000 1 <= x <= 1000 1 <= k <= 1000 0 <= val <= 100 每种方法 increment,push 以及 pop 分别最多调用 1000 次