0
点赞
收藏
分享

微信扫一扫

剑指 Offer打卡 栈队列堆


1、用两个栈实现队列

public class Solution {
public static void main(String[] args) {
}
//in
Stack<Integer> stack1 = new Stack<Integer>();
//out
Stack<Integer> stack2 = new Stack<Integer>();

public void push(int node) {
stack1.push(node);
}

public int pop() throws Exception {
if (stack2.isEmpty())
while (!stack1.isEmpty())
stack2.push(stack1.pop());

if (stack2.isEmpty())
throw new Exception("queue is empty");

return stack2.pop();
}
}
class CQueue {
//力扣
/**
* 用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,
* 分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof
*/
Deque<Integer> stack3;
Deque<Integer> stack4;

public CQueue() {
stack3 = new LinkedList<Integer>();
stack4 = new LinkedList<Integer>();
}

public void appendTail(int value) {
stack3.push(value);
}

public int deleteHead() {
// 如果第二个栈为空
if (stack4.isEmpty()) {
while (!stack3.isEmpty()) {
stack4.push(stack3.pop());
}
}
if (stack4.isEmpty()) {
return -1;
} else {
int deleteItem = stack4.pop();
return deleteItem;
}
}
}

2、包含min函数的栈

/**
* @author inke219223m
* <p>
* 实现一个包含 min() 函数的栈,该方法返回当前栈中最小的值。
* <p>
* <p>
* <p>
* Stack.peek()
* peek()函数返回栈顶的元素,但不弹出该栈顶元素。
* Stack.pop()
* pop()函数返回栈顶的元素,并且将该栈顶元素出栈。
*/
public class Solution {
public static void main(String[] args) {

}

private Stack<Integer> dataStack = new Stack<>();
private Stack<Integer> minStack = new Stack<>();

public void push(int node) {
dataStack.push(node);
minStack.push(minStack.empty() ? node : Math.min(minStack.peek(), node));
}

public void pop() {
dataStack.pop();
minStack.pop();
}

public int top() {
return dataStack.peek();
}

public int min() {
return minStack.peek();
}
}

//力扣
class MinStack {

Stack<Integer> dataStack;
Stack<Integer> minStack;

/** initialize your data structure here. */
public MinStack() {
dataStack = new Stack<>();
minStack = new Stack<>();
}

public void push(int x) {
dataStack.push(x);
minStack.push(minStack.empty() ? x : Math.min(minStack.peek(), x));
}

public void pop() {
dataStack.pop();
minStack.pop();
}

public int top() {
return dataStack.peek();
}

public int min() {
return minStack.peek();
}
}

/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(x);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.min();
*/

3、栈的压入弹出序列

/**
* @author inke219223m
* <p>
* Stack.peek()
* peek()函数返回栈顶的元素,但不弹出该栈顶元素。
* Stack.pop()
* pop()函数返回栈顶的元素,并且将该栈顶元素出栈。
*/
public class Solution {
public static void main(String[] args) {

}

/**
* 使用一个栈来模拟压入弹出操作。每次入栈一个元素后,都要判断一下栈顶元素是不是当前出栈序列
* popSequence 的第一个元素,如果是的话则执行出栈操作并将 popSequence 往后移一位,继续进行判断。
*
* @param pushA
* @param popA
* @return
*/
public boolean IsPopOrder(int[] pushA, int[] popA) {
int n = pushA.length;
Stack<Integer> stack = new Stack<>();
for (int pushIndex = 0, popIndex = 0; pushIndex < n; pushIndex++) {
stack.push(pushA[pushIndex]);
while (popIndex < n && !stack.empty() && stack.peek() == popA[popIndex]) {
stack.pop();
popIndex++;
}
}
return stack.isEmpty();
}

}

4、数据流中的中位数

/**
* @author inke219223m
* <p>
* 数据流中的中位数
* <p>
* 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。
* 如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
* 我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
*
* Stack.peek()
* peek()函数返回栈顶的元素,但不弹出该栈顶元素。
* Stack.pop()
* pop()函数返回栈顶的元素,并且将该栈顶元素出栈。
*/
public class Solution {
public static void main(String[] args) {

}

// 大顶堆,存储左半边元素
private PriorityQueue<Integer> left = new PriorityQueue<>((o1, o2) -> o2 - o1);
// 小顶堆,存储右半边元素
// 并且右半边元素都大于左半边
private PriorityQueue<Integer> right = new PriorityQueue<>();
// 当前数据流读入的元素个数
private int N = 0;

public void Insert(Integer val) {
// 插入要保证两个堆存于平衡状态
if (N % 2 == 0) {
/* N 为偶数的情况下插入到右半边。
* 因为右半边元素都要大于左半边,但是新插入的元素不一定比左半边元素来的大,
* 因此需要先将元素插入左半边,然后利用左半边为大顶堆的特点,取出堆顶元素即为最大元素,此时插入右半边
*/
left.add(val);
right.add(left.poll());
} else {
right.add(val);
left.add(right.poll());
}
N++;
}

public Double GetMedian() {
if (N % 2 == 0) return (left.peek() + right.peek()) / 2.0;
else return (double) right.peek();
}

}

5、最小的K个数

/**
* 最小的K个数
*/
public class Solution {
public static void main(String[] args) {
System.out.println(new Solution().GetLeastNumbers_Solution(new int[]{1, 2, 5, 10, 11, 9}, 3));

}

public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
if (k > input.length || k == 0) {
return new ArrayList<>();
}
//初始化时使用 Lambda 表达式 (o1, o2) -> o2 - o1 来实现大顶堆
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>((o1, o2) -> o2 - o1);
for (int num : input) {
priorityQueue.add(num);
if (priorityQueue.size() > k) {
priorityQueue.poll();
}
}
return new ArrayList<>(priorityQueue);
}

public int[] getLeastNumbers(int[] arr, int k) {
if (k > arr.length || k == 0) {
return new int[]{};
}
//初始化时使用 Lambda 表达式 (o1, o2) -> o2 - o1 来实现大顶堆
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>((o1, o2) -> o2 - o1);
for (int num : arr) {
priorityQueue.add(num);
if (priorityQueue.size() > k) {
priorityQueue.poll();
}
}
return priorityQueue.stream().mapToInt(Integer::valueOf).toArray();
}
}

6、滑动窗口的最大值

public class Solution {
public static void main(String[] args) {
System.out.println(new Solution().maxInWindows(new int[]{1, 2, 5, 9}, 3));
}

public ArrayList<Integer> maxInWindows(int [] num, int size) {
ArrayList<Integer> ret = new ArrayList<>();
if(size > num.length || size < 1) {
return new ArrayList<>();
}
// 大顶堆
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>((o1, o2) -> o2 - o1);
// 维护一个大小为 size 的大顶堆
for (int i = 0; i < size; i++) {
priorityQueue.add(num[i]);
}
ret.add(priorityQueue.peek());

for (int i = 0, j = i + size; j < num.length; i++, j ++) {
priorityQueue.remove(num[i]);
priorityQueue.add(num[j]);
ret.add(priorityQueue.peek());
}
return ret;
}

}

7、字符流中第一个不重复的字符

public class Solution {
public static void main(String[] args) {
Solution solution = new Solution();
String str = "aancbd";
for(int i = 0; i < str.length(); i++) {
solution.Insert(str.charAt(i));
System.out.print(solution.FirstAppearingOnce());
}
}

private int[]cnts = new int[128];
private Queue<Character> queue = new LinkedList<>();


//Insert one char from stringstream
public void Insert(char ch) {
cnts[ch]++;
queue.add(ch);
//非空&&数量大于1
//那么就移除
while (!queue.isEmpty() && cnts[queue.peek()] > 1) {
queue.poll();
}
}

//return the first appearence once char in current stringstream
public char FirstAppearingOnce() {
return queue.isEmpty() ? '#' : queue.peek();
}
}

代码仓库:https://gitee.com/codingce/codingce-leetcode


举报

相关推荐

0 条评论