432. All O`one Data Structure

来源:互联网 发布:智慧眼网络摄像机 编辑:程序博客网 时间:2024/05/21 20:25

Implement a data structure supporting the following operations:

  1. Inc(Key) - Inserts a new key with value 1. Or increments an existing key by 1. Key is guaranteed to be a non-empty string.
  2. Dec(Key) - If Key's value is 1, remove it from the data structure. Otherwise decrements an existing key by 1. If the key does not exist, this function does nothing. Key is guaranteed to be a non-empty string.
  3. GetMaxKey() - Returns one of the keys with maximal value. If no element exists, return an empty string "".
  4. GetMinKey() - Returns one of the keys with minimal value. If no element exists, return an empty string "".

Challenge: Perform all these in O(1) time complexity.

思路:因为insert和delete要O(1),所以要用HashTable,且key为cnt,value为HashSet
 * 
 * 因为getMax和getMin要O(1),那用数组,把cnt作为index行吗?
 * 这样求max还是要遍历数组,题目只要求获得max和min,
 * 应该用linkedList,插入的时候排好序,最前面的是最大的cnt,最后面是最小的cnt
 * 再用个双向链表就可以在O(1)时间取出
 * 
 * 因为JDK自带的LinkedList并不能实现O(1)的时间找到某个Node,
 * 而LinkedHashSet虽然能在O(1)时间内查找和删除,但是并不能O(1)查min,max
 * 所以还是要自己写个HashTable + double LinkedList(得自己实现)
 * 
 *  JDK为什么不自己实现一个这样的类呢??

head --- ValueNode1 ---- ValueNode2 ---- ... ---- ValueNodeN --- tail               |               |                       |                           first           first                   first                           |               |                       |                          KeyNodeA        KeyNodeE                KeyNodeG                         |               |                       |                          KeyNodeB        KeyNodeF                KeyNodeH                         |                                       |                          KeyNodeC                                KeyNodeI                         |                                                                  KeyNodeD                                                   

public class AllOne {class Node {Node next, prev;int cnt = 0;private Node(int cnt) {this.cnt = cnt;}// Set<Integer> keys = new HashSet<Integer>();}HashMap<Integer, HashSet<String>> cnt2set = new HashMap<Integer, HashSet<String>>();HashMap<String, Integer> key2cnt = new HashMap<String, Integer>();// HashMap<String, Node> nodes = new HashMap<String, Node>();// LinkedList<Integer> q = new LinkedList<Integer>();//LinkedHashSet<Integer> q = new LinkedHashSet<Integer>();Node head = new Node(-1), tail = new Node(-1);Map<Integer, Node> cnt2node = new HashMap<Integer, Node>();    /** Initialize your data structure here. */    public AllOne() {        head.next = tail;        tail.prev = head;    }        public void inc(String key) {    myinc(key);//    try {//    myinc(key);//    } catch (Exception e) {//    e.printStackTrace();//    }    }        public void dec(String key) {    mydec(key);//    try {//    mydec(key);//    } catch (Exception e) {//    e.printStackTrace();//    }    }        /** Inserts a new key <Key> with value 1. Or increments an existing key by 1. */    public void myinc(String key) {        if(key2cnt.containsKey(key)) {        int orig = key2cnt.get(key);        key2cnt.put(key, orig+1);// 1. key2cnt        if(!cnt2set.containsKey(orig+1))// 2. cnt2set        cnt2set.put(orig+1, new HashSet<String>());        cnt2set.get(orig).remove(key);        cnt2set.get(orig+1).add(key);                // 3. linkedlist        if(!cnt2node.containsKey(orig+1)) {        Node t = new Node(orig+1), tt = cnt2node.get(orig);        t.next = tt;        t.prev = tt.prev;        tt.prev = t;        tt.prev.next = t;        cnt2node.put(orig+1, t);        }                if(cnt2set.get(orig).size() == 0) {//        map.remove(orig);      // 可以不remove,只要在链表中把对应cnt值得node删掉就行        Node node = cnt2node.get(orig);        node.prev.next = node.next;        node.next.prev = node.prev;        cnt2node.remove(orig);        }                } else {        key2cnt.put(key, 1);        if(!cnt2set.containsKey(1))        cnt2set.put(1, new HashSet<String>());        cnt2set.get(1).add(key);        if(tail.prev.cnt != 1) {        Node t = new Node(1);        t.prev = tail.prev;        t.next = tail;        tail.prev.next = t;        tail.prev = t;        cnt2node.put(1, t);        }        }    }        /** Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */    public void mydec(String key) {        if(!key2cnt.containsKey(key) || key2cnt.get(key) == 0)return;        int orig = key2cnt.get(key);        if(orig > 1) {        key2cnt.put(key, key2cnt.get(key)-1);        cnt2set.get(orig).remove(key);        cnt2set.get(orig-1).add(key);                if(!cnt2node.containsKey(orig-1)) {        Node t = new Node(orig-1), tt = cnt2node.get(orig);        t.next = tt.next;        t.prev = tt;        tt.next.prev = t;        tt.next = t;        cnt2node.put(orig-1, t);        }                if(cnt2set.get(orig).size() == 0) {        Node node = cnt2node.get(orig);        node.prev.next = node.next;        node.next.prev = node.prev;        cnt2node.remove(orig);        }                } else {        key2cnt.put(key, 0);        cnt2set.get(orig).remove(key);                if(cnt2set.get(1).size() == 0) {        Node node = cnt2node.get(1);        node.prev.next = node.next;        node.next.prev = node.prev;        cnt2node.remove(orig);        }        }    }        /** Returns one of the keys with maximal value. */    public String getMaxKey() {    if(head.next == tail)return "";        return cnt2set.get(head.next.cnt).iterator().next();// 从set中获取一个数    }        /** Returns one of the keys with Minimal value. */    public String getMinKey() {    if(head.next == tail)return "";        return cnt2set.get(tail.prev.cnt).iterator().next();// 从set中获取一个数    }}

还是有bug,用try-catch也没调试出来

原创粉丝点击