1、最小栈
问题描述:
设计一个支持 push
,pop
,top
操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack
类:
MinStack()
初始化堆栈对象。void push(int val)
将元素val推入堆栈。void pop()
删除堆栈顶部的元素。int top()
获取堆栈顶部的元素。int getMin()
获取堆栈中的最小元素。
示例:
示例 1:
输入: ["MinStack","push","push","push","getMin","pop","top","getMin"] [[],[-2],[0],[-3],[],[],[],[]] 输出: [null,null,null,null,-3,null,0,-2] 解释: MinStack minStack = new MinStack(); minStack.push(-2); minStack.push(0); minStack.push(-3); minStack.getMin(); --> 返回 -3. minStack.pop(); minStack.top(); --> 返回 0. minStack.getMin(); --> 返回 -2.
思路: 为避免时间复杂度过大,除了普通栈stack外,多准备一个辅助栈minstack,辅助栈用来保存当前栈内最小元素,在此基础上进行入栈和出栈操作。
代码:
public class MinStack {
private Stack<Integer> stack;
private Stack<Integer> minStack;
public MinStack() {
this.stack = new Stack<>();
this.minStack = new Stack<>();
}
public void push(int val) {
stack.push(val);
if(minStack.empty()) {
minStack.push(val);
}else {
int x = minStack.peek();
if (x >= val) {
minStack.push(val);
}else {
return;
}
}
}
public void pop() {
if(stack.empty()) {
return;
}
int x = stack.pop();
if(x == minStack.peek()) {
minStack.pop();
}else {
return;
}
}
public int top() {
if(stack.empty()) {
return -1;
}
return stack.peek();
}
public int getMin() {
if(minStack.empty()) {
return -1;
}
return minStack.peek();
}
}
复杂度分析:
时间复杂度:O(1)
空间复杂度:O(n)
2、链表中倒数第k个节点
问题描述:
给定一个头节点为 head
的链表用于记录一系列核心肌群训练项目编号,请查找并返回倒数第 cnt
个训练项目编号。
示例:
示例 1:
输入:head = [2,4,7,8], cnt = 1 输出:8
思路:让p1指针先指向头节点,p2指针指向头节点后第cnt个节点,将两指针同时后移,直至p2指向空时,p1指针指向的就是所求节点。
代码:
class Solution {
public ListNode trainingPlan(ListNode head, int cnt) {
ListNode p1=head;
ListNode p2=head;
for(int i=0;i<cnt;i++){
p2=p2.next;
}
while(p2!=null){
p1=p1.next;
p2=p2.next;
}
return p1;
}
}
复杂度分析:
时间复杂度:O(n)
空间复杂度:O(1)