type none struct{} type pair struct { key int set map[string]none } type AllOne struct { m map[string]*list.Element li *list.List } /** Initialize your data structure here. */ func Constructor() AllOne { return AllOne{ m: make(map[string]*list.Element), li: list.New(), } } /** Inserts a new key with value 1. Or increments an existing key by 1. */ func (this *AllOne) Inc(key string) { if val, ok := this.m[key]; ok { // Increments next := val.Next() if next == nil || val.Value.(pair).key+1 < next.Value.(pair).key { // Insert after next = this.li.InsertAfter(pair{val.Value.(pair).key + 1, map[string]none{key: none{}}}, val) } else { // Increment after next.Value.(pair).set[key] = none{} } this.m[key] = next if len(val.Value.(pair).set) == 1 { // Remove current element this.li.Remove(val) } else { // Remove from set delete(val.Value.(pair).set, key) } } else { // Inserts if this.li.Len() == 0 || 1 < this.li.Front().Value.(pair).key { // Push front this.li.PushFront(pair{1, map[string]none{key: none{}}}) } else { // Move to ones set this.li.Front().Value.(pair).set[key] = none{} } this.m[key] = this.li.Front() } } /** Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */ func (this *AllOne) Dec(key string) { if val, ok := this.m[key]; ok { if val.Value.(pair).key == 1 { // Removes if len(val.Value.(pair).set) == 1 { // Remove whole element this.li.Remove(val) } else { // Remove from set delete(val.Value.(pair).set, key) } delete(this.m, key) // Remove from map } else { // Decrements prev := val.Prev() if prev == nil || prev.Value.(pair).key < val.Value.(pair).key-1 { // Insert before prev = this.li.InsertBefore(pair{val.Value.(pair).key - 1, map[string]none{key: none{}}}, val) } else { // Move to prev set prev.Value.(pair).set[key] = none{} } this.m[key] = prev if len(val.Value.(pair).set) == 1 { // Remove current element this.li.Remove(val) } else { delete(val.Value.(pair).set, key) // Remove from set } } } } /** Returns one of the keys with maximal value. */ func (this *AllOne) GetMaxKey() string { if this.li.Len() != 0 { set := this.li.Back().Value.(pair).set for k := range set { return k } } return "" } /** Returns one of the keys with Minimal value. */ func (this *AllOne) GetMinKey() string { if this.li.Len() != 0 { set := this.li.Front().Value.(pair).set for k := range set { return k } } return "" } /** * Your AllOne object will be instantiated and called as such: * obj := Constructor(); * obj.Inc(key); * obj.Dec(key); * param_3 := obj.GetMaxKey(); * param_4 := obj.GetMinKey(); */