04课、栈、队列、双端队列
栈、队列、双端队列 - 添加、删除 都是O(1) 查询是O(n) priority Queue 优先队列 - 插入O(1) 取出 O(log(n))
function isValid(s){
const stack = []
for(let i=0;i<s.length;i++){
const c = s[i]
if(c === '{' || c === '[' || c === '(' ){
// 是左括号,入栈
stack.push(c)
} else {
if (stack.length === 0) return false
const top = stack[stack.length - 1] // 栈顶
if( top === '(' && c === ')' || top === '[' && c === ']' || top === '{' && c === '}'){
stack.pop()
} else {
return false
}
}
}
return stack.length === 0
}
- 实现最小栈 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。 leetcode-cn.com/problems/mi… 1、辅助栈情况
// 1、维护两个数组,辅助栈情况
let MinStack = function(){
this.x_stack = []
this.min_stack = []
}
MinStack.prototype.push = function(x){
this.x_stack.push(x)
this.min_stack.push(Math.min(this.min_stack[this.min_stack.length -1], x))
}
MinStack.prototype.pop = function(){
this.x_stack.pop()
this.min_stack.pop()
}
MinStack.prototype.top = function(){
return this.x_stack[this.x_stack.length -1]
}
MinStack.prototype.getMin = function(){
return this.min_stack[this.min_stack.length -1]
}
// 2、维护一个数组栈,注意去除下一个最小的时候,原来最小值丢失的情况. 最小值入栈
public void push(int x) {
//当前值更小
if(x <= min){
//将之前的最小值保存
stack.push(min);
//更新最小值
min=x;
}
stack.push(x);
}
- 柱状图中最大的矩形 leetcode-cn.com/problems/la…
1、暴力求解。以当前位置:
①、往左看,看最多能向左延伸多长,找到大于等于当前柱形高度的最左边元素的下标。
②、往右看,看最多能向右延伸多长,找到大于等于当前柱形高度的最右边元素的下标。
var largestRectangleArea = function(heights) {
let maxArea = 0
let j=0
if(heights.length <= 0){ return heights }
for(let i=0;i<heights.length;i++){
let lflag = 0
let rflag = 0
j=i
while(i>0 && j>=0 && --j<i && heights[j]>=heights[i]){
lflag = i-j
}
j=i
while(++j<heights.length && heights[j]>=heights[i]){
rflag = j-i
}
maxArea = Math.max(maxArea, heights[i] * (lflag+rflag+1))
}
return maxArea
};
2、单调栈 stack
function largestRectangleArea(heights){
if(!heights || !heights.length) return 0
// 重要地方
heights.unshift(0)
heights.push(0)
const stack = []
let maxArea = 0
const getStackLastItem = () => stack[stack.length -1]
for(let i=0;i<heights.length ;i++){
while(stack.length && heights[getStackLastItem()] > heights[i]){
const j=stack.pop()
const width = i - getStackLastItem() -1
maxArea = Math.max(maxArea, width * heights[j])
}
stack.push(i)
}
}
- 滑动窗口最大值 leetcode-cn.com/problems/sl…
- 设计循环双端队列 leetcode-cn.com/problems/de…
class MyCircularDeque {
constructor(k){
this.capacity = k+1;
this.arr = new Array(this.capacity);
this.front = 0; // 头部指向第 1 个存放元素的位置 //插入时,先减,再赋值 //删除时,索引 +1(注意取模)
this.rear= 0; // 尾部指向下一个插入元素的位置 // 插入时,先赋值,再加 // 删除时,索引 -1(注意取模)
}
insertFront(value){
if(isFull()){ return false }
this.front = (this.front-1+this.capacity)%this.capacity
this.arr[this.front] = value;
return true;
}
insertLast(value){
if(isFull()){ return false }
this.arr[this.rear] = value;
this.rear = (this.rear+1) % this.capacity;
return true;
}
deleteFront(){
if(isEmpty()){ return false }
this.front = (this.front+1) % this.capacity;
return true;
}
deleteLast(){
if(isEmpty()) { return false};
this.rear = (this.rear-1+this.capacity) % this.capacity;
return true;
}
getFront(){
if(isEmpty()){ return -1};
return this.arr[this.front];
}
getRear(){
if(isEmpty()){ return -1};
// 当 rear 为 0 时防止数组越界, rear指向的是下一个插入的元素的位置,元素为空,需要-1;
return this.arr[(this.rear-1+this.capacity) % this.capacity];
}
isEmpty(){
return this.front == this.rear;
}
isFull(){
return (this.rear+1) % this.capacity == this.front;
}
}