Advertisement
1988coder

All O`one Data Structure

Sep 22nd, 2018
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 3.58 KB | None | 0 0
  1. class AllOne {
  2.    
  3.     Bucket head;
  4.     Bucket tail;
  5.     Map<Integer, Bucket> valueBucketMap;
  6.     Map<String, Integer> keyValueMap;
  7.    
  8.     private class Bucket {
  9.         int value;
  10.         Set<String> keySet;
  11.         Bucket pre;
  12.         Bucket next;
  13.        
  14.         public Bucket(int val) {
  15.             value = val;
  16.             keySet = new LinkedHashSet<>();
  17.             pre = null;
  18.             next = null;
  19.         }
  20.     }
  21.    
  22.     /** Initialize your data structure here. */
  23.     public AllOne() {
  24.         head = new Bucket(-1);
  25.         tail = new Bucket(-1);
  26.         head.next = tail;
  27.         tail.pre = head;
  28.         valueBucketMap = new HashMap<>();
  29.         keyValueMap = new HashMap<>();
  30.     }
  31.    
  32.     /** Inserts a new key <Key> with value 1. Or increments an existing key by 1. */
  33.     public void inc(String key) {
  34.         if (keyValueMap.containsKey(key)) {
  35.             changeKeyValue(key, 1);
  36.         } else {
  37.             keyValueMap.put(key, 1);
  38.             if (head.next.value != 1) {
  39.                 addBucketAfter(new Bucket(1), head);
  40.                 valueBucketMap.put(1, head.next);
  41.             }
  42.             head.next.keySet.add(key);
  43.         }
  44.     }
  45.    
  46.     /** Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */
  47.     public void dec(String key) {
  48.         if (!keyValueMap.containsKey(key)) {
  49.             return;
  50.         }
  51.         int value = keyValueMap.get(key);
  52.         if (value == 1) {
  53.             keyValueMap.remove(key);
  54.             removeKeyFromBucket(valueBucketMap.get(value), key);
  55.         } else {
  56.             changeKeyValue(key, -1);
  57.         }
  58.     }
  59.    
  60.     /** Returns one of the keys with maximal value. */
  61.     public String getMaxKey() {
  62.         if (tail.pre == head) {
  63.             return "";
  64.         }
  65.         return tail.pre.keySet.iterator().next();
  66.     }
  67.    
  68.     /** Returns one of the keys with Minimal value. */
  69.     public String getMinKey() {
  70.         if (tail.pre == head) {
  71.             return "";
  72.         }
  73.         return head.next.keySet.iterator().next();
  74.     }
  75.    
  76.     private void changeKeyValue(String key, int offset) {
  77.         int curVal = keyValueMap.get(key);
  78.         keyValueMap.put(key, curVal + offset);
  79.         Bucket curBucket = valueBucketMap.get(curVal);
  80.         Bucket newBucket = valueBucketMap.get(curVal + offset);
  81.         if (newBucket == null) {
  82.             newBucket = new Bucket(curVal + offset);
  83.             valueBucketMap.put(curVal + offset, newBucket);
  84.             if (offset == 1) {
  85.                 addBucketAfter(newBucket, curBucket);
  86.             } else {
  87.                 addBucketAfter(newBucket, curBucket.pre);
  88.             }
  89.         }
  90.         newBucket.keySet.add(key);
  91.         removeKeyFromBucket(curBucket, key);
  92.     }
  93.    
  94.     private void removeKeyFromBucket(Bucket bucket, String key) {
  95.         bucket.keySet.remove(key);
  96.         if (bucket.keySet.size() == 0) {
  97.             bucket.pre.next = bucket.next;
  98.             bucket.next.pre = bucket.pre;
  99.             bucket.next = null;
  100.             bucket.pre = null;
  101.             valueBucketMap.remove(bucket.value);
  102.         }
  103.     }
  104.    
  105.     private void addBucketAfter(Bucket newBucket, Bucket preBucket) {
  106.         newBucket.pre = preBucket;
  107.         newBucket.next = preBucket.next;
  108.         preBucket.next.pre = newBucket;
  109.         preBucket.next = newBucket;
  110.     }
  111. }
  112.  
  113. /**
  114.  * Your AllOne object will be instantiated and called as such:
  115.  * AllOne obj = new AllOne();
  116.  * obj.inc(key);
  117.  * obj.dec(key);
  118.  * String param_3 = obj.getMaxKey();
  119.  * String param_4 = obj.getMinKey();
  120.  */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement