[LeetCode]432. All O`one Data Structure

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

用bucket保存同一value的key,bucket是一个双向指针。bucket里面有keySet,有value。保存全局变量keyMap和bucketMap以便于在O(1)时间内找到bucket。



public class AllOne {
    
    Bucket head;
    Bucket tail;
    HashMap<String, Integer> keyMap;
    HashMap<Integer, Bucket> bucketMap;
    
    private class Bucket {
        int count;
        Set<String> keySet;
        Bucket pre;
        Bucket next;
        public Bucket(int count) {
            this.count = count;
            keySet = new HashSet<>();
        }
    }

    /** Initialize your data structure here. */
    public AllOne() {
        head = new Bucket(Integer.MIN_VALUE);
        tail = new Bucket(Integer.MIN_VALUE);
        head.next = tail;
        tail.pre = head;
        keyMap = new HashMap<>();
        bucketMap = new HashMap<>();
    }
    
    /** Inserts a new key <Key> with value 1. Or increments an existing key by 1. */
    public void inc(String key) {
        if (keyMap.containsKey(key)) {
            changeVal(key, 1);
        } else {
            keyMap.put(key, 1);
            if (head.next.count != 1) {
                insertAfter(head, new Bucket(1));
            }
            head.next.keySet.add(key);
            bucketMap.put(1, head.next);
        }
    }
    
    /** Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */
    public void dec(String key) {
        if (keyMap.containsKey(key)) {
            int count = keyMap.get(key);
            if (count == 1) {
                keyMap.remove(key);
                removeKeyFromBucket(bucketMap.get(count), key);
            } else {
                changeVal(key, -1);
            }
        }
    }
    
    /** Returns one of the keys with maximal value. */
    public String getMaxKey() {
        return tail.pre == head ? "" : (String) tail.pre.keySet.iterator().next();
    }
    
    /** Returns one of the keys with Minimal value. */
    public String getMinKey() {
        return head.next == tail ? "" : (String) head.next.keySet.iterator().next();
    }
    
    private void changeVal(String key, int offset) {
        int count = keyMap.get(key);
        keyMap.put(key, count + offset);
        Bucket curBucket = bucketMap.get(count);
        Bucket newBucket;
        if (bucketMap.containsKey(count + offset)) {
            newBucket = bucketMap.get(count + offset);
        } else {
            newBucket = new Bucket(count + offset);
            bucketMap.put(count + offset, newBucket);
            insertAfter(offset == 1 ? curBucket : curBucket.pre, newBucket);
        }
        newBucket.keySet.add(key);
        removeKeyFromBucket(curBucket, key);
    }
    
    private void insertAfter(Bucket pre, Bucket after) {
        after.next = pre.next;
        after.pre = pre;
        pre.next.pre = after;
        pre.next = after;
    }
    
    private void removeKeyFromBucket(Bucket bucket, String key) {
        bucket.keySet.remove(key);
        if (bucket.keySet.size() == 0) {
            removeFromBucketList(bucket);
            bucketMap.remove(bucket.count);
        }
    }
    
    private void removeFromBucketList(Bucket bucket) {
        bucket.pre.next = bucket.next;
        bucket.next.pre = bucket.pre;
        bucket.next = null;
        bucket.pre = null;
    }
}

/**
 * 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、付费专栏及课程。

余额充值