LRU缓存
import java.util.HashMap;
import java.util.Map;
class LRUCache {
private Map<Integer,Node> map;
private DoubleList cache;
private int capacity;
public LRUCache(int capacity){
map = new HashMap<>();
cache = new DoubleList();
this.capacity = capacity;
}
public int get(int key){
if(!map.containsKey(key)){
return -1;
}
int val = map.get(key).val;
put(key,val);
return val;
}
public void put(int key,int val){
Node node = new Node(key,val);
if(map.containsKey(key)){
cache.remove(map.get(key));
cache.addFirst(node);
map.put(key,node);
}else{
if(capacity==cache.size()){
Node last = cache.removeLast();
map.remove(last.key);
}
cache.addFirst(node);
map.put(key,node);
}
}
}
class Node{
int key;
int val;
Node prev;
Node next;
public Node(int key,int val){
this.key=key;
this.val=val;
}
}
class DoubleList {
private Node head;
private Node tail;
private int size;
public DoubleList(){
head = new Node(0,0);
tail = new Node(0,0);
head.next=tail;
tail.prev=head;
size=0;
}
public void addFirst(Node node){
node.next = head.next;
node.prev = head;
head.next.prev = node;
head.next = node;
size++;
}
public void remove(Node node){
node.prev.next = node.next;
node.next.prev = node.prev;
size--;
}
public Node removeLast(){
if(tail.prev==head){
return null;
}
Node last = tail.prev;
remove(last);
return last;
}
public int size(){
return size;
}
}
LFU
class Node{
int key;
int value;
int freq=1;
public Node(){}
public Node(int key,int value){
this.key=key;
this.value = value;
}
}
class LFUCache {
private Map<Integer,Node> cache;
private Map<Integer, LinkedHashSet<Node>> freqMap;
private int capacity;
private int minFreq;
private int size;
public LFUCache(int capacity) {
cache = new HashMap<>(capacity);
freqMap = new HashMap<>();
this.capacity = capacity;
}
public int get(int key) {
Node node = cache.get(key);
if(node==null){
return -1;
}
freqInc(node);
return node.value;
}
public void put(int key, int value) {
if(capacity==0){
return;
}
Node node = cache.get(key);
if(node!=null){
node.value = value;
freqInc(node);
}else{
if(size==capacity){
Node deadNode = deleteNode();
cache.remove(deadNode.key);
size--;
}
Node newNode = new Node(key,value);
cache.put(key,newNode);
addNode(newNode);
size++;
}
}
private void freqInc(Node node){
int freq = node.freq;
LinkedHashSet<Node> set = freqMap.get(freq);
set.remove(node);
if(freq==minFreq&&set.size()==0){
minFreq = freq+1;
}
node.freq++;
LinkedHashSet<Node> newSet = freqMap.get(freq+1);
if(newSet==null){
newSet = new LinkedHashSet<>();
freqMap.put(freq+1,newSet);
}
newSet.add(node);
}
private void addNode(Node node){
LinkedHashSet<Node> set = freqMap.get(1);
if(set==null){
set = new LinkedHashSet<>();
freqMap.put(1,set);
}
set.add(node);
minFreq = 1;
}
private Node deleteNode(){
LinkedHashSet<Node> set = freqMap.get(minFreq);
Node deadNode = set.iterator().next();
set.remove(deadNode);
return deadNode;
}
}
skipList
import java.util.Random;
class SkipListNode {
int value;
SkipListNode[] next;
public SkipListNode(int value, int level) {
this.value = value;
this.next = new SkipListNode[level];
}
}
public class SkipList {
private static final int MAX_LEVEL = 16;
private static final double PROBABILITY = 0.5;
private int levelCount = 1;
private SkipListNode head = new SkipListNode(-1, MAX_LEVEL);
private Random random = new Random();
public SkipListNode find(int value) {
SkipListNode p = head;
for (int i = levelCount - 1; i >= 0; i--) {
while (p.next[i] != null && p.next[i].value < value) {
p = p.next[i];
}
}
if (p.next[0] != null && p.next[0].value == value) {
return p.next[0];
}
return null;
}
public void insert(int value) {
int level = randomLevel();
SkipListNode newNode = new SkipListNode(value, level);
SkipListNode[] update = new SkipListNode[level];
SkipListNode p = head;
for (int i = level - 1; i >= 0; i--) {
while (p.next[i] != null && p.next[i].value < value) {
p = p.next[i];
}
update[i] = p;
}
for (int i = level - 1; i >= 0; i--) {
newNode.next[i] = update[i].next[i];
update[i].next[i] = newNode;
}
if (levelCount < level) {
levelCount = level;
}
}
public void delete(int value) {
SkipListNode[] update = new SkipListNode[levelCount];
SkipListNode p = head;
for (int i = levelCount - 1; i >= 0; i--) {
while (p.next[i] != null && p.next[i].value < value) {
p = p.next[i];
}
update[i] = p;
}
if (p.next[0] != null && p.next[0].value == value) {
for (int i = levelCount - 1; i >= 0; i--) {
if (update[i].next[i] != null && update[i].next[i].value == value) {
update[i].next[i] = update[i].next[i].next[i];
}
}
}
}
private int randomLevel() {
int level = 1;
while (random.nextDouble() < PROBABILITY && level < MAX_LEVEL) {
level++;
}
return level;
}
}
从前序和中序遍历序列构建二叉树
class Solution {
private int[] preorder;
private int[] inorder;
private HashMap<Integer,Integer> idx_map;
private int pre_idx=0;
public TreeNode buildTree(int[] preorder, int[] inorder) {
this.preorder = preorder;
this.inorder = inorder;
idx_map = new HashMap<>();
int idx = 0;
for(Integer val : inorder){
idx_map.put(val,idx++);
}
return helper(0,inorder.length);
}
private TreeNode helper(int start,int end){
if(start==end){
return null;
}
int rootVal = preorder[pre_idx];
TreeNode root = new TreeNode(rootVal);
int index = idx_map.get(rootVal);
pre_idx++;
root.left = helper(start,index);
root.right = helper(index+1,end);
return root;
}
}
从中序和后序遍历序列构建二叉树
class Solution {
private int[] inorder;
private int[] postorder;
private Map<Integer,Integer> map;
private int idx;
public TreeNode buildTree(int[] inorder, int[] postorder) {
this.inorder = inorder;
this.postorder = postorder;
this.map = new HashMap<>();
this.idx = inorder.length-1;
int idx_map = idx;
for(Integer val : inorder){
map.put(val,idx_map--);
}
return helper(0,idx+1);
}
private TreeNode helper(int start,int end){
if(start==end){
return null;
}
int rootVal = postorder[idx];
TreeNode root = new TreeNode(rootVal);
int index = map.get(rootVal);
idx--;
root.right = helper(start,index);
root.left = helper(index+1,end);
return root;
}
}
字典树
class TrieNode {
TrieNode[] children;
boolean isEndOfWord;
public TrieNode() {
children = new TrieNode[26];
isEndOfWord = false;
}
}
class Trie {
private TrieNode root;
public Trie() {
root = new TrieNode();
}
public void insert(String word) {
TrieNode current = root;
for (int i = 0; i < word.length(); i++) {
char ch = word.charAt(i);
int index = ch - 'a';
if (current.children[index] == null) {
current.children[index] = new TrieNode();
}
current = current.children[index];
}
current.isEndOfWord = true;
}
public boolean search(String word) {
TrieNode current = root;
for (int i = 0; i < word.length(); i++) {
char ch = word.charAt(i);
int index = ch - 'a';
if (current.children[index] == null) {
return false;
}
current = current.children[index];
}
return current != null && current.isEndOfWord;
}
public boolean startsWith(String prefix) {
TrieNode current = root;
for (int i = 0; i < prefix.length(); i++) {
char ch = prefix.charAt(i);
int index = ch - 'a';
if (current.children[index] == null) {
return false;
}
current = current.children[index];
}
return true;
}
}