1.设计循环队列:
/**
* @param {number} k
*/
var MyCircularQueue = function(k) {
this.size = k;
this.font = -1;
this.rear = -1;
this.quene = new Array(k);
};
/**
* @param {number} value
* @return {boolean}
*/
MyCircularQueue.prototype.enQueue = function(value) {
if(this.isEmpty()) {
this.font++;
this.rear++;
this.quene[this.rear]=value;
return true;
}
if (this.isFull()) {
return false;
}
this.rear = (this.rear + 1) % this.size;
this.quene[this.rear]=value;
return true;
};
/**
* @return {boolean}
*/
MyCircularQueue.prototype.deQueue = function() {
if (this.isEmpty()) {
return false;
}
if (this.rear === this.font) {
// this.quene[this.rear] = null;
this.rear = -1;
this.font = -1;
return true;
}
// this.quene[this.font] = null;
this.font = (this.font + 1) % this.size;
return true;
};
/**
* @return {number}
*/
MyCircularQueue.prototype.Front = function() {
return this.isEmpty() ? -1 : this.quene[this.font];
};
/**
* @return {number}
*/
MyCircularQueue.prototype.Rear = function() {
return this.isEmpty() ? -1 : this.quene[this.rear];
};
/**
* @return {boolean}
*/
MyCircularQueue.prototype.isEmpty = function() {
return this.font === -1 && this.rear === -1;
};
/**
* @return {boolean}
*/
MyCircularQueue.prototype.isFull = function() {
return (this.rear + 1)%this.size === this.font;
};
/**
* Your MyCircularQueue object will be instantiated and called as such:
* var obj = new MyCircularQueue(k)
* var param_1 = obj.enQueue(value)
* var param_2 = obj.deQueue()
* var param_3 = obj.Front()
* var param_4 = obj.Rear()
* var param_5 = obj.isEmpty()
* var param_6 = obj.isFull()
*/
2. 最小栈:
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
- MinStack() 初始化堆栈对象。
- void push(int val) 将元素val推入堆栈。
- void pop() 删除堆栈顶部的元素。
- int top() 获取堆栈顶部的元素。
- int getMin() 获取堆栈中的最小元素。
var MinStack = function () {
// 主栈指针
this.head = null
// 辅助栈指针
this.subHead = null
};
/**
* @param {number} x
* @return {void}
*/
MinStack.prototype.push = function (x) {
const newItem = {
data: x,
next: null
}
const subNewItem = {
data: x,
next: null
}
// 主栈判断逻辑
if (!this.head) {
this.head = newItem
} else {
newItem.next = this.head
this.head = newItem
}
// 辅助栈判断逻辑
if (!this.subHead) {
this.subHead = subNewItem
} else {
if (this.subHead.data >= x) {
subNewItem.next = this.subHead
this.subHead = subNewItem
}
}
};
/**
* @return {void}
*/
MinStack.prototype.pop = function () {
if (!this.head) return false
const result = this.head.data
if (this.subHead && result === this.subHead.data) {
this.subHead = this.subHead.next
}
this.head = this.head.next
return result
};
/**
* @return {number}
*/
MinStack.prototype.top = function () {
if (!this.head) return false
return this.head.data
};
/**
* @return {number}
*/
MinStack.prototype.getMin = function () {
if (!this.subHead) return false
return this.subHead.data
};
3. 每日温度:
给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。
/**
* @param {number[]} temperatures
* @return {number[]}
*/
var dailyTemperatures = function(temperatures) {
let res = new Array(temperatures.length).fill(0);
let stack = [];
for(let i = 0; i < temperatures.length; i++ ) {
while(stack.length > 0 && temperatures[i] > temperatures[stack[stack.length-1]]) {
let currIdx = stack.pop();
res[currIdx] = i - currIdx;
}
stack.push(i);
}
return res;
};
4. 你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。
请你计算该表达式。返回一个表示表达式值的整数。
注意:
- 有效的算符为 '+'、'-'、'*' 和 '/' 。
- 每个操作数(运算对象)都可以是一个整数或者另一个表达式。
- 两个整数之间的除法总是 向零截断 。
- 表达式中不含除零运算。
- 输入是一个根据逆波兰表示法表示的算术表达式。
- 答案及所有中间计算结果可以用 32 位 整数表示。
/**
* @param {string[]} tokens
* @return {number}
*/
var evalRPN = function(tokens) {
let stack = [];
for (let i = 0; i < tokens.length; i++) {
if(['+', '-', '*', '/'].includes(tokens[i])){
let numberT = stack.pop();
let numberB = stack.pop();
let res;
switch(tokens[i]) {
case '+':
res = numberB + numberT;
break;
case '-':
res = numberB - numberT;
break;
case '*':
res = numberB * numberT;
break;
case '/':
res = numberB / numberT >= 0 ? Math.floor(numberB / numberT) : Math.ceil(numberB / numberT);
break;
default:
}
stack.push(res);
} else {
stack.push(Number(tokens[i]));
}
}
return stack.pop();
};
5. 环形链表:
给你一个链表的头节点 head
,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true
。 否则,返回 false
。
var hasCycle = function(head) {
let fast = head
let slow = head
while(fast && fast.next) {
fast = fast.next.next
slow = slow.next
if(fast === slow) return true
}
return false
};
6. 环形链表 II:
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
/**
* @param {ListNode} head
* @return {ListNode}
*/
var detectCycle = function(head) {
let fast = head
let slow = head
while(fast && fast.next) {
fast = fast.next.next
slow = slow.next
if(fast === slow) break;
}
if(!fast || !fast.next) return null;
fast = head;
while(fast !== slow){
fast = fast.next;
slow = slow.next;
}
return fast;
};