leetcode刷题笔记-design

2013. Detect Squares

​​​​​​​

 

class DetectSquares:

    def __init__(self):
        self.c = Counter()  # (x, y) 的个数
        self.xy = collections.defaultdict(Counter)

    def add(self, point: List[int]) -> None:
        x, y = point
        self.c[x, y] += 1
        self.xy[x][y] += 1

    def count(self, point: List[int]) -> int:
        x, y = point
        re = 0
        for y2 in self.xy[x]:
            if y2 == y:
                continue # 要 positive area, 和当前重叠的不考虑
            re += self.c[x, y2] * self.c[x + y2 - y, y] * self.c[x + y2 - y, y2]
            re += self.c[x, y2] * self.c[x + y - y2, y] * self.c[x + y - y2, y2]
        return re

 

588. Design In-Memory File System 

在trie分类

362. Design Hit Counter

class HitCounter(object):
    # hit: O(1). get_hit: O(300). This solution will scale perfectly!
    def __init__(self):
        self.count = [[i, 0] for i in xrange(1, 301)] # i是timestamp, 0是频率

    def hit(self, timestamp):
        idx = (timestamp - 1) % 300
        if self.count[idx][0] == timestamp:
            self.count[idx][1] += 1
        else:
            self.count[idx][0] = timestamp
            self.count[idx][1] = 1
        

    def getHits(self, timestamp):
        res = 0
        for time, c in self.count:
            if timestamp - time < 300:
                res += c
        return res

348. Design Tic-Tac-Toe

class TicTacToe(object):
    def __init__(self, n):
        self.row, self.col = [0] * n, [0]*n
        self.diag = self.anti_diag = 0
        self.n = n
        
    def move(self, row, col, player):
        offset = 1 if player == 1 else -1
        if row == col:
            self.diag += offset
        if row + col == self.n - 1:
            self.anti_diag += offset
        self.row[row] += offset
        self.col[col] += offset
        if self.n in (self.row[row], self.col[col], self.diag, self.anti_diag):
            return 1
        if -self.n in (self.row[row], self.col[col], self.diag, self.anti_diag):
            return 2
        return 0

794. Valid Tic-Tac-Toe State 

情况1. X 的个数要比O 多一个 或者相等。

2.不能有X,O都赢的情况

3. X赢的话,X的个数一定是比O 多一个

4.O赢的话,O的个数一定是等于X的个数

class Solution(object):
    def validTicTacToe(self, board):
        r, c = [0]*3, [0]*3
        dia, anti_dia = 0, 0
        count = 0
        for i in xrange(3):
            for j in xrange(3):
                offset = 0
                if board[i][j] == 'X':
                    offset = 1
                    count += 1
                elif board[i][j] == 'O':
                    offset = -1
                    count -= 1
                r[i] += offset
                c[j] += offset
                if i == j:
                    dia += offset
                if i + j == 2:
                    anti_dia += offset
        if 3 in (r+c+[dia]+[anti_dia]) and (-3 in (r+c+[dia]+[anti_dia]) or count != 1):
            return False
        
        if count < 0 or count > 1:
            return False
        
        if -3 in (r+c+[dia]+[anti_dia]) and count != 0:
            return False
        return True

281. Zigzag Iterator

class ZigzagIterator(object):

    def __init__(self, v1, v2):
        self.q = [v for v in (v1, v2) if v]

    def next(self):
        temp = self.q.pop(0)
        res = temp.pop(0)
        if temp: self.q.append(temp)
        return res
        
    def hasNext(self):
        if self.q:
            return True
        return False
        

146. LRU Cache

 解法一:OrderedDict , 太好用了,但是太取巧了

class LRUCache(object):

    def __init__(self, capacity):
        """
        :type capacity: int
        """
        self.dic = collections.OrderedDict()
        self.remain = capacity
        

    def get(self, key):
        """
        :type key: int
        :rtype: int
        """
        if key not in self.dic:
            return -1
        v = self.dic.pop(key)
        self.dic[key] = v
        return v
        

    def put(self, key, value):
        """
        :type key: int
        :type value: int
        :rtype: void
        """
        if key in self.dic:
            self.dic.pop(key)
        else:
            if self.remain > 0:
                self.remain -= 1
            else:
                self.dic.popitem(last=False)
        self.dic[key] = value

方法二:链表结构,链表特点,如果节点没有被引用,则节点会被回收(删除)

class Node:
    def __init__(self, key, value):
        self.key = key
        self.value = value
        self.pre = None
        self.next = None
        
class LRUCache(object):

    def __init__(self, capacity):
        """
        :type capacity: int
        """
        self.dic = {}
        self.capacity = capacity
        self.head = Node(0, 0)
        self.tail = Node(0, 0)
        self.head.next = self.tail
        self.tail.pre = self.head
        

    def get(self, key):
        """
        :type key: int
        :rtype: int
        """
        if key in self.dic:
            node = self.dic[key]
            self._remove(node)
            self._add(node)
            return node.value
        else:
            return -1
        

    def put(self, key, value):
        """
        :type key: int
        :type value: int
        :rtype: void
        """
        if key in self.dic:
            self._remove(self.dic[key])
        node = Node(key, value)
        self._add(node)
        self.dic[key] = node
        if len(self.dic) > self.capacity:
            n = self.head.next
            self._remove(n)
            del self.dic[n.key]
     
    
    def _remove(self, node):
        preNode = node.pre
        nextNode = node.next
        preNode.next = nextNode
        nextNode.pre = preNode
    
    def _add(self, node):
        preNode = self.tail.pre
        preNode.next = node
        node.pre = preNode
        node.next = self.tail
        self.tail.pre = node
                

460. LFU Cache

class LFUCache(object):
    def __init__(self, capacity):
        self.remain = capacity
        self.freqDic = collections.defaultdict(collections.OrderedDict)  # freq: [key:value, ]
        self.leastFreq = 1  # so that we can delete least frequent node
        self.node = {}  # node key: (value, freq)
        
    def _update(self, key, value=None):
        old_freq = self.node[key][1]
        if not value:
            value = self.node[key][0]
        self.node[key] = (value, old_freq+1)
        self.freqDic[old_freq].pop(key)
        if len(self.freqDic[self.leastFreq]) == 0:  # if the update node is the only one left with least frequence, then leastFreq+1
            self.leastFreq += 1
        self.freqDic[old_freq+1][key] = value
        
    def get(self, key):
        if key not in self.node:
            return -1
        self._update(key)
        return self.node[key][0]

    def put(self, key, value):
        if key in self.node:
            self._update(key, value)
        else:
            self.node[key] = (value, 1)
            self.freqDic[1][key] = value  # add before remove, so if the capacity is 0, you add then delete 
            if self.remain == 0:
                removed_node = self.freqDic[self.leastFreq].popitem(last=False)  # return: (key, value)
                self.node.pop(removed_node[0])
            else:
                self.remain -= 1
            self.leastFreq = 1

353. Design Snake Game

class SnakeGame(object):

    def __init__(self, width, height, food):
        """
        Initialize your data structure here.
        @param width - screen width
        @param height - screen height 
        @param food - A list of food positions
        E.g food = [[1,1], [1,0]] means the first food is positioned at [1,1], the second is at [1,0].
        :type width: int
        :type height: int
        :type food: List[List[int]]
        """
        self.m = collections.defaultdict(dict)  # 二维list会out of memory
        self.food = food
        if food:
            x, y = self.food.pop(0)
            self.m[x][y] = 'F'
            self.m[0][0] = 'S'
        self.row = height
        self.col = width
        self.head = (0, 0)
        self.tail = [(0, 0)]
        self.eat = 0

    def move(self, d):
        """
        Moves the snake.
        @param direction - 'U' = Up, 'L' = Left, 'R' = Right, 'D' = Down 
        @return The game's score after the move. Return -1 if game over. 
        Game over when snake crosses the screen boundary or bites its body.
        :type direction: str
        :rtype: int
        """
        
        def outBorder(x, y):
            if 0 <= x < self.row and 0 <= y < self.col:
                return False
            return True
        
        if d == 'U':
            X, Y = -1, 0
        elif d == 'D':
            X, Y = 1, 0
        elif d == 'L':
            X, Y = 0, -1
        elif d == 'R':
            X, Y = 0, 1
        
        x, y = self.head
        X, Y = x+X, y+Y
        # Game over
        if outBorder(X, Y):
            return -1
        
        tx, ty = self.tail[0]
        
        if (X, Y) != (tx, ty) and self.m[X].get(Y) == 'S':  # 头部前进,尾巴就跟着缩走一格
            return -1
        
        
        # food
        if self.m[X].get(Y) == 'F':
            self.eat += 1
            if self.food:
                fx, fy = self.food.pop(0)
                self.m[fx][fy] = 'F'  # new food
        else:
            tail = self.tail.pop(0)
            self.m[tail[0]][tail[1]] = 0  # remove tail
            
        self.m[X][Y] = 'S'  
        self.head = X, Y  # update head
        self.tail.append([X, Y])
        return self.eat
                        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值