8.22 - hard - 84

2017-08-23  本文已影响0人  健时总向乱中忙

432. All O`one Data Structure

基本的想法就是利用一个双向链表来维持单调性,每个node的value就是当前key出现的次数,
然后利用keys这个set来维护当前这个value次数下有多少个key。这样取头或者尾就可以得到最大key或者最小key,然后在用一个hash来从key映射到key所在的node,每次增加或者减少value的时候,就移动key所在的node,并且更新映射。

class Node:
    def __init__(self, value, next, prev, key):
        self.next = next
        self.prev = prev
        self.value = value
        self.keys = {key}
        
class DoubleList:
    def __init__(self):
        self.head = Node(-1, None, None, "")
        self.tail = Node(-1, None, None, "")
        self.head.next = self.tail
        self.tail.prev = self.head
        
    def insertAfter(self, n, val, key):
        nn = Node(val, n.next, n, key)
        n.next = nn
        nn.next.prev = nn
        return nn
        
    def remove(self, n):
        n.prev.next = n.next
        n.next.prev = n.prev
        del n
        
class AllOne(object):
    
    def __init__(self):
        self.dll = DoubleList()
        self.keys = {}

    def inc(self, key):
        if key not in self.keys:
            n = self.dll.insertAfter(self.dll.head, 0, key)
            self.keys[key] = n
        else:
            n = self.keys[key]
        
        if n.value + 1 == n.next.value:
            # merge with next
            self.keys[key] = n.next
            n.keys.remove(key)
            n.next.keys.add(key)
        elif len(n.keys) == 1:
            # increment in place
            n.value += 1
        else:
            # insert new node
            nn = self.dll.insertAfter(n, n.value+1, key)
            self.keys[key] = nn
            n.keys.remove(key)
        
        #Garbage collection
        if len(n.keys) <= 0:
            self.dll.remove(n)

    def dec(self, key):
        if key not in self.keys:
            return
        else:
            n = self.keys[key]
            
        if n.value==1:
            # remove key/node
            del self.keys[key]
            n.keys.remove(key)
        elif n.value - 1 == n.prev.value:
            # merge with previous
            self.keys[key] = n.prev
            n.keys.remove(key)
            n.prev.keys.add(key)
        elif len(n.keys) == 1:
            # decrement in place
            n.value -= 1
        else:
            # insert new node
            nn = self.dll.insertAfter(n.prev, n.value-1, key)
            n.keys.remove(key)
            self.keys[key] = nn
        
        # Garbage collection
        if len(n.keys) <= 0:
            self.dll.remove(n)

    def getMaxKey(self):
        if self.dll.head.next.value == -1:
            return ""
        for k in self.dll.tail.prev.keys:
            break
        return k

    def getMinKey(self):
        if self.dll.head.next.value == -1:
            return ""
        for k in self.dll.head.next.keys:
            break
        return k
上一篇下一篇

猜你喜欢

热点阅读