05、字节跳动-数据结构

1、最小栈

public class OneHundredAndFiftyFive {
    //直接用ArrayList好像好一点
    private int maxSize = 100;
    private int add = 10;
    private int[] nums;
    private int index = 0;
    public OneHundredAndFiftyFive() {
        nums = new int[maxSize];
    }

    public void push(int x) {
        if(index < maxSize){
            nums[index++] = x;
        }else{
            int[] tem = new int[maxSize+add];
            for (int i = 0; i < maxSize; i++) {
                tem[i] = nums[i];
            }
            nums = tem;
            maxSize = maxSize + add;
            nums[index++] = x;
        }
    }

    public void pop() {
        if(index > 0)
            index--;
    }

    public int top() {
        if (index > 0) {
            int t = index - 1;
            return nums[t];
        }
        return 0;
    }

    public int getMin() {
        if(index == 0){
            return 0;
        }
        int min = nums[0];
        for (int i = 1; i < index; i++) {
            if(nums[i] < min){
                min = nums[i];
            }
        }
        return min;
    }

    public static void main(String[] args) {
        OneHundredAndFiftyFive tt = new OneHundredAndFiftyFive();
        System.out.println(tt.getMin());
        tt.push(-2);
        tt.push(0);
        tt.push(-3);
        System.out.println(tt.getMin());
        tt.pop();
        System.out.println(tt.top());
        System.out.println(tt.getMin());
    }
}

原文:https://blog.csdn.net/RBreeze/article/details/81407685

2、LRU缓存机制

import java.util.*;
 
class Node{
	int key;
	int value;
	Node next;
	Node pre;
	public Node(int key,int value,Node pre, Node next){
		this.key = key;
		this.value = value;
		this.pre = pre;
		this.next = next;
	}
}
 
public class LRUCache {
	int capacity;
	int count;//cache size
	Node head;
	Node tail;
	HashMap<Integer,Node>hm;
    public LRUCache(int capacity) { //only initial 2 Node is enough, head/tail
    	this.capacity = capacity;
    	this.count = 2;
    	this.head = new Node(-1,-1,null,null);
    	this.tail = new Node(-2,-2,this.head,null);
    	this.head.next = this.tail;
        hm = new HashMap<Integer,Node>();
        hm.put(this.head.key, this.head);
        hm.put(this.tail.key, this.tail);
    }
    
    public int get(int key) {
    	int value = -1;
    	if(hm.containsKey(key)){
    		Node nd = hm.get(key);
    		value = nd.value;
    		detachNode(nd); //detach nd from current place
    		insertToHead(nd); //insert nd into head
    	}
		return value;
    }
    
    public void put(int key, int value) {
    	if(hm.containsKey(key)){ //update
    		Node nd = hm.get(key);
    		nd.value = value;
    		//move to head
    		detachNode(nd); //detach nd from current place
    		insertToHead(nd); //insert nd into head
    	}else{ //add
    		Node newNd = new Node(key,value,null,this.head);
    		this.head.pre = newNd; //insert into head
    		this.head = newNd;
    		hm.put(key, newNd); //add into hashMap
    		this.count ++;
    		if(this.count > capacity){ //need delete node
    			removeNode();
    		}
    	}
    }
    //common func
    public void insertToHead(Node nd){
    	this.head.pre = nd;
    	nd.next = this.head;
    	nd.pre = null;
    	this.head = nd;
    }
    public void detachNode(Node nd){
    	nd.pre.next = nd.next;
    	if(nd.next!=null){
    		nd.next.pre = nd.pre;
    	}else{
    		this.tail = nd.pre;
    	}
    }
    public void removeNode(){ //remove from tail
		int tailKey = this.tail.key;
		this.tail = this.tail.pre;
		this.tail.next = null;
		hm.remove(tailKey);
		this.count --;
    }
    public void printCache(){
    	System.out.println("\nPRINT CACHE ------ ");
    	System.out.println("count: "+count);
    	System.out.println("From head:");
    	Node p = this.head;
    	while(p!=null){
    		System.out.println("key: "+p.key+" value: "+p.value);
    		p = p.next;
    	}
    	System.out.println("From tail:");
    	p = this.tail;
    	while(p!=null){
    		System.out.println("key: "+p.key+" value: "+p.value);
    		p = p.pre;
    	}
    	
    }
    
    public static void main(String[] args){
    	LRUCache lc = new LRUCache(3);
    	lc.printCache();
    	
    	lc.put(1, 1);
    	lc.put(2, 2);
    	lc.put(3, 3);
    	lc.printCache();
    	
    	lc.get(2);
    	lc.printCache();
    	
    	lc.put(4, 4);
    	lc.printCache();
    	
    	lc.get(1);
    	lc.printCache();
    	
    	lc.put(3, 33);
    	lc.printCache();	
    }
}

原文:https://blog.csdn.net/karen0310/article/details/75039604

3、全 O(1) 的数据结构

class AllOne {
public:
    /** Initialize your data structure here. */
    AllOne() {
        
    }
    
    /** Inserts a new key <Key> with value 1. Or increments an existing key by 1. */
    void inc(string key) {
        if (!m.count(key)) {
            if (buckets.empty() || buckets.back().val != 1) {
                auto newBucket = buckets.insert(buckets.end(), {1, {key}});
                m[key] = newBucket;
            } else {
                auto newBucket = --buckets.end();
                newBucket->keys.insert(key);
                m[key] = newBucket;
            }
        } else {
            auto curBucket = m[key], lastBucket = (--m[key]);
            if (lastBucket == buckets.end() || lastBucket->val != curBucket->val + 1) {
                auto newBucket = buckets.insert(curBucket, {curBucket->val + 1, {key}});
                m[key] = newBucket;
            } else {
                lastBucket->keys.insert(key);
                m[key] = lastBucket;
            }
            curBucket->keys.erase(key);
            if (curBucket->keys.empty()) buckets.erase(curBucket);
        }
    }
    
    /** Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */
    void dec(string key) {
        if (!m.count(key)) return;
        auto curBucket = m[key];
        if (curBucket->val == 1) {
            curBucket->keys.erase(key);
            if (curBucket->keys.empty()) buckets.erase(curBucket);
            m.erase(key);
            return;
        }
        auto nextBucket = ++m[key];
        if (nextBucket == buckets.end() || nextBucket->val != curBucket->val - 1) {
            auto newBucket = buckets.insert(nextBucket, {curBucket->val - 1, {key}});
            m[key] = newBucket;
        } else {
            nextBucket->keys.insert(key);
            m[key] = nextBucket;
        }
        curBucket->keys.erase(key);
        if (curBucket->keys.empty()) buckets.erase(curBucket);
    }
    
    /** Returns one of the keys with maximal value. */
    string getMaxKey() {
        return buckets.empty() ? "" : *(buckets.begin()->keys.begin());
    }
    
    /** Returns one of the keys with Minimal value. */
    string getMinKey() {
        return buckets.empty() ? "" : *(buckets.rbegin()->keys.begin());
    }
private:
    struct Bucket { int val; unordered_set<string> keys; };
    list<Bucket> buckets;
    unordered_map<string, list<Bucket>::iterator> m;
};

/**
 * Your AllOne object will be instantiated and called as such:
 * AllOne obj = new AllOne();
 * obj.inc(key);
 * obj.dec(key);
 * string param_3 = obj.getMaxKey();
 * string param_4 = obj.getMinKey();
 */

原文:https://blog.csdn.net/zrh_CSDN/article/details/84140614 

参考:https://www.cnblogs.com/grandyang/p/6012229.html

猜你喜欢

转载自blog.csdn.net/applehub/article/details/84937155