介绍
有这么一类题,会考察利用已有的数据结构(包含某些算法)来设计一种新的数据结构。
经典例题
- 【力扣-232. 用栈实现队列】
/**
* 主要难点在于pop时要记得检查s2栈是否为空
*/
import java.util.Stack;
//leetcode submit region begin(Prohibit modification and deletion)
class MyQueue {
private Stack<Integer> s1;
private Stack<Integer> s2;
/** Initialize your data structure here. */
public MyQueue() {
this.s1 = new Stack<>();
this.s2 = new Stack<>();
}
/** Push element x to the back of queue. */
public void push(int x) {
s1.push(x);
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
if (s2.isEmpty()) {
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
}
return s2.pop();
}
/** Get the front element. */
public int peek() {
if (s2.isEmpty()) {
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
}
return s2.peek();
}
/** Returns whether the queue is empty. */
public boolean empty() {
return s1.isEmpty() && s2.isEmpty();
}
}
- 【力扣-225. 用队列实现栈】
/**
* 用两个队列实现栈,这思路真滴是巧妙呀~
* 主要是push方法,写得妙~
*/
import java.util.LinkedList;
import java.util.Queue;
//leetcode submit region begin(Prohibit modification and deletion)
class MyStack {
private Queue<Integer> q1;
private Queue<Integer> q2;
/** Initialize your data structure here. */
public MyStack() {
this.q1 = new LinkedList<>();
this.q2 = new LinkedList<>();
}
/** Push element x onto stack. */
public void push(int x) {
q1.offer(x);
while (!q2.isEmpty()) {
q1.offer(q2.poll());
}
Queue temp = q1;
q1 = q2;
q2 = temp;
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
return q2.poll();
}
/** Get the top element. */
public int top() {
return q2.peek();
}
/** Returns whether the stack is empty. */
public boolean empty() {
return q2.isEmpty();
}
}
- 【力扣-146. LRU 缓存机制】
class LRUCache {
private int capacity;
private LinkedHashMap<Integer, Integer> cache;
public LRUCache(int capacity) {
this.cache = new LinkedHashMap<>();
this.capacity = capacity;
}
public int get(int key) {
if (!cache.containsKey(key)) {
return -1;
}
int val = cache.remove(key);
cache.put(key, val);
return cache.get(key);
}
public void put(int key, int value) {
if (cache.containsKey(key)) {
cache.remove(key);
}
if (cache.size() == capacity) {
cache.remove(cache.entrySet().iterator().next().getKey());
}
cache.put(key, value);
}
}
总结:
LRU 缓存算法的核心数据结构就是哈希链表,双向链表和哈希表的结合体。,长这样:
- 【力扣-295. 数据流的中位数】
/**
* 中位数用一个大顶堆,一个小顶堆,真滴神呐
*/
class MedianFinder {
private PriorityQueue<Integer> small;
private PriorityQueue<Integer> large;
/** initialize your data structure here. */
public MedianFinder() {
// small 小顶堆存放的是较大的值,large 大顶堆存放的是较小的值
// 当large.size - small.size > 1时,large中的值会移动到small中!
this.small = new PriorityQueue<>((o1, o2) -> o1-o2);
this.large = new PriorityQueue<>((o1, o2) -> o2-o1);
}
public void addNum(int num) {
if (small.size() > large.size()) {
small.offer(num);
large.offer(small.poll());
} else {
large.offer(num);
small.offer(large.poll());
}
}
public double findMedian() {
if (small.size() == large.size()) {
return (double)(small.peek() + large.peek())/2.0;
} else if (small.size() > large.size()){
return (double)small.peek();
} else {
return (double)large.peek();
}
}
}
- 【Union-Find 算法应用】
详细参看并查集 刷题总结