Leetcode: All O`one Data Structure
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的更多相关文章
- [LeetCode] All O`one Data Structure 全O(1)的数据结构
Implement a data structure supporting the following operations: Inc(Key) - Inserts a new key with va ...
- [LeetCode] Two Sum III - Data structure design 两数之和之三 - 数据结构设计
Design and implement a TwoSum class. It should support the following operations:add and find. add - ...
- LeetCode Two Sum III - Data structure design
原题链接在这里:https://leetcode.com/problems/two-sum-iii-data-structure-design/ 题目: Design and implement a ...
- [LeetCode] Add and Search Word - Data structure design 添加和查找单词-数据结构设计
Design a data structure that supports the following two operations: void addWord(word) bool search(w ...
- 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 ...
- leetcode@ [211] Add and Search Word - Data structure design
https://leetcode.com/problems/add-and-search-word-data-structure-design/ 本题是在Trie树进行dfs+backtracking ...
- leetcode面试准备:Add and Search Word - Data structure design
leetcode面试准备:Add and Search Word - Data structure design 1 题目 Design a data structure that supports ...
- LeetCode 170. Two Sum III - Data structure design (两数之和之三 - 数据结构设计)$
Design and implement a TwoSum class. It should support the following operations: add and find. add - ...
- 【LeetCode】170. Two Sum III – Data structure design
Difficulty:easy More:[目录]LeetCode Java实现 Description Design and implement a TwoSum class. It should ...
随机推荐
- 定时器的fireDate指的是触发时间
1.定时器开启后,会在经过设定的时间间隔后才会执行第一次定时操作.而不是立马开启. NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval: ...
- C# 委托和Lambda---基础
[委托]是一个类可以把一个方法当作另一个方法的参数使用. 声明委托:delegate string 委托名(参数列表);//跟定义方法一样,只是没有方法体,必须使用关键字delegate使用委托的函数 ...
- LVS + KEEPAlived 配置 DIR模式
1 .1 Lvs LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统.本项目在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件项目 ...
- DataContract
DataContractAttribute Class is in the System.Runtime.Serialization namespace. But you should add ref ...
- 单例 (JAVA)
java中单例模式是一种常见的设计模式,以下是它的特点: 单例类只能有一个实例. 单例类必须自己创建自己的唯一实例. 单例类必须给所有其他对象提供这一实例 第一种(懒汉,线程不安全): 1 publ ...
- iBatis in 语句参数传入方法
刚刚开始在工作中用到iBatis 在用到in去查询或者删除 我本来是传递一个String的参数,但是总是报以下的错误
- JAVA创建并写入内容到xlsx文件
首先需要在web项目中导入jxl.jar 包 //action中代码 public String downloadReport(){ String path = System.getPr ...
- Daily Scrum 10.28
今天是周一,大家基本都结束了设计阶段转入代码实现的阶段,由于同志们感觉这部分的难度比较大,所以经过讨论延长了这部分的估计时间. 下面是今天的Task统计: 所有迭代的状态:
- c# select标签绑定枚举,并以Description做Text显示
今天在做项目时遇到一个问题: 开发中有些字段是枚举类型如 Dept 企业表中可能有个字段 Property 性质 0:事业单位,1:私企,2:外企,但有时我们不会单独为性质这个字段定义一张表, 而是在 ...
- jquery无法修改网页标题,无法修改网页标题
今天遇到一个问题,搜索时动态修改网页标题,用jquery的这段代码无效,无论FF还是IE $("title").html("new title"); 后来只好用 ...