Implement a data structure supporting the following operations:

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.
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.
GetMaxKey() - Returns one of the keys with maximal value. If no element exists, return an empty string "".
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.

Solution: O(1) time complexity

解题思路主要参考了网友ivancjw的帖子,数据结构参考了https://discuss.leetcode.com/topic/65634/java-ac-all-strict-o-1-not-average-o-1-easy-to-read用bucket,思路是,我们建立一个次数分层的结构,次数多的在顶层,每一层放相同次数的key值,例如下面这个例子:

"A": 4, "B": 4, "C": 2, "D": 1

那么用我们设计的结构保存出来就是:

row0: val = 4, keys = {"A", "B"}
row1: val = 2, keys = {"C"}
row2: val = 1, keys = {"D"}

 public class AllOne {
public class Bucket {
int count;
Bucket prev;
Bucket next;
HashSet<String> keySet;
public Bucket(int num) {
this.count = num;
this.keySet = new HashSet<String>();
}
} Bucket head;
Bucket tail;
HashMap<String, Integer> keyCountMap;
HashMap<Integer, Bucket> countBucketMap; /** Initialize your data structure here. */
public AllOne() {
this.head = new Bucket(Integer.MIN_VALUE);
this.tail = new Bucket(Integer.MAX_VALUE);
head.next = tail;
tail.prev = head;
this.keyCountMap = new HashMap<String, Integer>();
this.countBucketMap = 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 (keyCountMap.containsKey(key)) {
change(key, 1);
}
else {
keyCountMap.put(key, 1);
if (head.next.count != 1) { //dont have the 1 bucket
addBucketAfter(new Bucket(1), head);
countBucketMap.put(1, head.next);
}
head.next.keySet.add(key);
}
} /** Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */
public void dec(String key) {
if (keyCountMap.containsKey(key)) {
int count = keyCountMap.get(key);
if (count == 1) {
keyCountMap.remove(key);
removeKeyFromBucket(countBucketMap.get(count), key);
}
else change(key, -1);
}
} /** Returns one of the keys with maximal value. */
public String getMaxKey() {
return tail.prev==head? "" : (String)tail.prev.keySet.iterator().next();
} /** Returns one of the keys with Minimal value. */
public String getMinKey() {
return head.next==tail? "" : (String)head.next.keySet.iterator().next();
} public void change(String key, int offset) {
//get count, update keyCountMap
int count = keyCountMap.get(key);
keyCountMap.put(key, count+offset); //get current bucket
Bucket curBucket = countBucketMap.get(count); //new bucket
Bucket newBucket;
if (countBucketMap.containsKey(count+offset)) {
newBucket = countBucketMap.get(count+offset);
}
else {
newBucket = new Bucket(count+offset);
countBucketMap.put(count+offset, newBucket);
addBucketAfter(newBucket, (offset==1? curBucket : curBucket.prev));
}
newBucket.keySet.add(key);
removeKeyFromBucket(curBucket, key);
} public void removeKeyFromBucket(Bucket cur, String key) {
cur.keySet.remove(key);
if (cur.keySet.size() == 0) {
removeBucketFromList(cur);
countBucketMap.remove(cur.count);
}
} public void removeBucketFromList(Bucket cur) {
cur.prev.next = cur.next;
cur.next.prev = cur.prev;
cur.next = null;
cur.prev = null;
} public void addBucketAfter(Bucket bucket, Bucket preBucket) {
bucket.prev = preBucket;
bucket.next = preBucket.next;
preBucket.next.prev = bucket;
preBucket.next = bucket;
}
} /**
* 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();
*/

Solution 2: 如果不要求O(1)time, 这个用两个heap方法很常规

 public class AllOne {

     class Node{
String key;
int val;
public Node(String key, int val) {
this.key = key;
this.val = val;
}
}
/** Initialize your data structure here. */
HashMap<String, Node> map;
PriorityQueue<Node> minQ;
PriorityQueue<Node> maxQ;
public AllOne() {
map = new HashMap<String, Node>();
minQ = new PriorityQueue<Node>(new Comparator<Node>(){
public int compare(Node a, Node b) {
return a.val - b.val;
}
});
maxQ = new PriorityQueue<Node>(new Comparator<Node>(){
public int compare(Node a, Node b) {
return b.val - a.val;
}
});
} /** Inserts a new key <Key> with value 1. Or increments an existing key by 1. */
public void inc(String key) {
if (!map.containsKey(key)) {
map.put(key, new Node(key, 1));
Node node = map.get(key);
minQ.add(node);
maxQ.add(node);
} else {
Node node = map.get(key);
minQ.remove(node);
maxQ.remove(node);
node.val++;
map.put(key, node);
minQ.add(node);
maxQ.add(node);
}
} /** Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */
public void dec(String key) {
if (map.containsKey(key)) {
Node node = map.get(key);
if (node.val == 1) {
map.remove(key);
minQ.remove(node);
maxQ.remove(node);
} else {
minQ.remove(node);
maxQ.remove(node);
node.val--;
map.put(key, node);
minQ.add(node);
maxQ.add(node);
}
}
} /** Returns one of the keys with maximal value. */
public String getMaxKey() {
return maxQ.isEmpty() ? "" : maxQ.peek().key;
} /** Returns one of the keys with Minimal value. */
public String getMinKey() {
return minQ.isEmpty() ? "" : minQ.peek().key;
}
}

Leetcode: All O`one Data Structure的更多相关文章

  1. [LeetCode] All O`one Data Structure 全O(1)的数据结构

    Implement a data structure supporting the following operations: Inc(Key) - Inserts a new key with va ...

  2. [LeetCode] Two Sum III - Data structure design 两数之和之三 - 数据结构设计

    Design and implement a TwoSum class. It should support the following operations:add and find. add - ...

  3. LeetCode Two Sum III - Data structure design

    原题链接在这里:https://leetcode.com/problems/two-sum-iii-data-structure-design/ 题目: Design and implement a ...

  4. [LeetCode] Add and Search Word - Data structure design 添加和查找单词-数据结构设计

    Design a data structure that supports the following two operations: void addWord(word) bool search(w ...

  5. Java for LeetCode 211 Add and Search Word - Data structure design

    Design a data structure that supports the following two operations: void addWord(word)bool search(wo ...

  6. leetcode@ [211] Add and Search Word - Data structure design

    https://leetcode.com/problems/add-and-search-word-data-structure-design/ 本题是在Trie树进行dfs+backtracking ...

  7. leetcode面试准备:Add and Search Word - Data structure design

    leetcode面试准备:Add and Search Word - Data structure design 1 题目 Design a data structure that supports ...

  8. LeetCode 170. Two Sum III - Data structure design (两数之和之三 - 数据结构设计)$

    Design and implement a TwoSum class. It should support the following operations: add and find. add - ...

  9. 【LeetCode】170. Two Sum III – Data structure design

    Difficulty:easy  More:[目录]LeetCode Java实现 Description Design and implement a TwoSum class. It should ...

随机推荐

  1. Android -- ProgressBar(进度条的使用)

    我们在开发程序是经常会需要软件全屏显示.自定义标题(使用按钮等控件)和其他的需求,今天这一讲就是如何控制Android应用程序的窗体显示. requestWindowFeature可以设置的值有:(具 ...

  2. [代码] 类似 YYText 将表情文本转换成表情字符

    一,经历 1> 由于工作需要,得把 UITextView 中的属性文本转换成普通文字,并将处理后的普通文字转换成属性文本. 2> 将属性文本转换成普通文字简单,可以调用属性文本的enume ...

  3. mysql in 命令

    SQL: select * from table where id IN (3,6,9,1,2,5,8,7); SQL: select * from table where id IN ($str); ...

  4. Windows 下安装使用docker swarm machine docker toolbox

    下载docker 集成安装环境 http://get.daocloud.io/#install-toolbox 这个网站很不错,下载 这个集成了 docker docker-machine ,还有gi ...

  5. lua语法备忘录

    1.三元表达式 a?b:c => a and b or c 2.循环数组 local keys = args.kvs:get_keys() local arr = xstring.split(k ...

  6. javascript原型方法

    function createXMLHttp() { if(window.XMLHttpRequest){ return new XMLHttpRequest(); } else if(window. ...

  7. java使用poi读取ppt文件和poi读取excel、word示例

    java使用poi读取ppt文件和poi读取excel.word示例 http://www.jb51.net/article/48092.htm

  8. ambari无法登陆 设备空间不足

    1.ambari无法登陆,Unable to connect to Ambari Server ? ——>原因:端口8080被spark占用.修改${SPARK_HOME}/sbin/start ...

  9. js添加确认删除操作注意事项

    function delsure(){ if(confirm('确认删除吗?')){ return true;//点击确定则返回这里的内容 }else{ return false; } } 在表单中添 ...

  10. c语言中的文件流

    一.打开和关闭文件 #include int main( void ) { FILE* pReadFile = fopen( "E:\\mytest.txt", "r&q ...