【leetcode每日刷题】432. All O`one Data Structure

https://leetcode.com/problems/all-oone-data-structure/

https://www.cnblogs.com/Dylan-Java-NYC/p/6491294.html

很像LFU的机制.

  • 用Bucket组成一个double linked list. 按照Bucket的count从小到大排序.
  • inc 把key move到下一个Bucket.
  • dec把key move到前一个Bucket.
  • min key就在前面, head.next.
  • max key就出现在后面, tail.pre.
  • Time Complexity: inc, dec, getaMaxKey, getMinKey, O(1).
  • Space: O(n). n是现有key的个数.
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

class AllOne {
    Bucket head;
    Bucket tail;
    Map<String, Integer> keyCount;
    Map<Integer, Bucket> countBucket;
    /** Initialize your data structure here. */
    public AllOne() {
        head = new Bucket(-1);
        tail = new Bucket(-1);
        head.next = tail;
        tail.pre = head;
        keyCount = new HashMap<String, Integer>();
        countBucket = new HashMap<Integer, Bucket>();
    }
    
    /** Inserts a new key <Key> with value 1. Or increments an existing key by 1. */
    public void inc(String key) {
        if(keyCount.containsKey(key)){
            moveKey(key, 1);
        }else{
            keyCount.put(key, 1);
            if(head.next.count != 1){
                addBucketAfter(new Bucket(1), head);
            }
            head.next.keySet.add(key);
            countBucket.put(1, head.next);
        }
    }

    public void moveKey(String key, int step){
        int count = keyCount.get(key);
        keyCount.put(key, count+step);
        Bucket p = countBucket.get(count);
        Bucket moveToBucket;
        if(countBucket.containsKey(count+step)){
            moveToBucket = countBucket.get(count+step);
        }else{
            moveToBucket = new Bucket(count+step);
            countBucket.put(count+step, moveToBucket);
            addBucketAfter(moveToBucket, step == 1? p:p.pre);
        }
        moveToBucket.keySet.add(key);
        removeKeyFromBucket(p, key);
    }

    public void removeKeyFromBucket(Bucket cur, String key){
        cur.keySet.remove(key);
        if(cur.keySet.size() == 0){
            countBucket.remove(cur.count);
            cur.pre.next = cur.next;
            cur.next.pre = cur.pre;
        }
    }

    public void addBucketAfter(Bucket b, Bucket pre){
        Bucket temp = pre.next;
        pre.next = b;
        b.pre = pre;
        b.next = temp;
        temp.pre = b;
    }
    
    /** Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */
    public void dec(String key) {
        if(keyCount.containsKey(key)){
            int count = keyCount.get(key);
            if(count == 1){
                keyCount.remove(key);
                removeKeyFromBucket(countBucket.get(count), key);
            }else{
                moveKey(key, -1);
            }
        }
    }
  
    /** Returns one of the keys with maximal value. */
    public String getMaxKey() {
        return tail.pre == head? "":tail.pre.keySet.iterator().next();
    }
    
    /** Returns one of the keys with Minimal value. */
    public String getMinKey() {
        return head.next == tail? "":head.next.keySet.iterator().next();
    }
}

class Bucket{
    int count;
    Set<String> keySet;
    Bucket pre;
    Bucket next;

    public Bucket(int count){
        this.count = count;
        keySet = new LinkedHashSet<String>();
    }
}

/**
 * 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();
 */

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值