lc marathon 7.26

146. LRU 缓存

利用python的dic存入key是有顺序的

加入一个数: 如果该数存在,则删除原本的,重新加入该数 并更新value

                    如果该数不存在,且满了,则删除第一个key。没满则直接存

访问一个数:如果该数存在,则保留value,然后删除,重新再存

                    不存在,返回-1
class LRUCache:

    def __init__(self, capacity: int):
        self.dic={}
        self.cap=capacity


    def get(self, key: int) -> int:
        if key in self.dic.keys():
            value=self.dic[key]
            del self.dic[key]
            self.dic[key]=value
            return self.dic[key]
        return -1


    def put(self, key: int, value: int) -> None:
        if key in self.dic.keys():
            del self.dic[key]
         
        elif len(self.dic.keys())>=self.cap:
            del self.dic[list(self.dic.keys())[0]]
        self.dic[key]=value
130. 被围绕的区域

首先对边界上每一个’O’做深度优先搜索,将与其相连的所有’O’改为’-‘。然后遍历矩阵,将矩阵中所有’O’改为’X’,将矩阵中所有’-‘变为’O’

class Solution:
    def solve(self, board: List[List[str]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        """
    Do not return anything, modify board in-place instead.
    """
        for i in range(len(board)):
            if board[i][0]=='O':
                vis=[[ 0 for j in range(len(board[0]))] for i in range(len(board))]
                dfs(board,i,0,vis)
            if board[i][len(board[0])-1] == 'O':
                vis = [[0 for j in range(len(board[0]))] for i in range(len(board))]
                dfs(board,i,len(board[0])-1,vis)
        for j in range(len(board[0])):
            if board[0][j]=='O':
                vis=[[ 0 for j in range(len(board[0]))] for i in range(len(board))]
                dfs(board,0,j,vis)
            if board[len(board)-1][j] == 'O':
                vis = [[0 for j in range(len(board[0]))] for i in range(len(board))]
                dfs(board,len(board)-1,j,vis)
        for i in range(len(board)):
            for j in range(len(board[0])):
                if board[i][j]=='O':
                    board[i][j]='X'
                if board[i][j]=='-':
                    board[i][j]='O'
        
                
        
    


def dfs(board,i,j,visited):
    # 边界越界
    if i<0 or i>=len(board) or j<0 or j>=len(board[0]):
        return
    # 前进不了
    print(i,j)
    if board[i][j]=='X':
        return
    # 已经访问过
    if visited[i][j]==1:
        return 
    # 可以访问到的O,先用其他的代替
    if board[i][j]=='O':
        board[i][j]='-'
        visited[i][j]=1
        # 继续前进
        dfs(board, i - 1, j, visited)
        dfs(board, i + 1, j, visited)
        dfs(board, i, j-1, visited)
        dfs(board, i, j+1, visited)
        visited[i][j]=0
    return 
133. 克隆图

关键是建立旧节点到新节点的映射

然后用深度遍历即可

"""
# Definition for a Node.
class Node:
    def __init__(self, val = 0, neighbors = None):
        self.val = val
        self.neighbors = neighbors if neighbors is not None else []
"""
dic={}
ls=set()
class Solution:
    def cloneGraph(self, node: 'Node') -> 'Node':
        if node ==None:
            return None
        global dic,ls
        dic={}
        ls=set()
        dfs(node)
        for old_node in list(ls):
            dic[old_node].neighbors=[dic[old_neighbor] for old_neighbor in old_node.neighbors]
        return dic[node]



def dfs(node):
    global dic,ls
    if node==None:
        return
    if node in ls:
        return 
    # 复制 并建立旧节点-新节点的映射
    new_node=Node(val=node.val)
    dic[node] = new_node
    # 存原来的node
    ls.add(node)
    for inode in node.neighbors:
        dfs(inode)
    return

134. 加油站

有一个环形路上有n个站点; 每个站点都有一个好人或一个坏人; 好人会给你钱,坏人会收你一定的过路费,如果你带的钱不够付过路费,坏人会跳起来把你砍死; 问:从哪个站点出发,能绕一圈活着回到出发点?

首先考虑一种情况:如果全部好人给你 的钱加起来 小于 坏人收的过路费之和,那么总有一次你的钱不够付过路费,你的结局注定会被砍死。

假如你随机选一点 start 出发,那么你肯定会选一个有好人的站点开始,因为开始的时候你没有钱,遇到坏人只能被砍死;

现在你在start出发,走到了某个站点end,被end站点的坏人砍死了,说明你在 [start, end) 存的钱不够付 end点坏人的过路费,因为start站点是个好人,所以在 (start, end) 里任何一点出发,你存的钱会比现在还少,还是会被end站点的坏人砍死;

于是你重新读档,聪明的选择从 end+1点出发,继续你悲壮的征程; 终于有一天,你发现自己走到了尽头(下标是n-1)的站点而没有被砍死; 此时你犹豫了一下,那我继续往前走,身上的钱够不够你继续走到出发点Start?

当然可以,因为开始已经判断过,好人给你的钱数是大于等于坏人要的过路费的,你现在攒的钱完全可以应付 [0, start) 这一段坏人向你收的过路费。 这时候你的嘴角微微上扬,眼眶微微湿润,因为你已经知道这个世界的终极奥秘:Start就是这个问题的答案。

为什么如果k+1->end全部可以正常通行,且rest>=0就可以说明车子从k+1站点出发可以开完全程?

  • 因为,起始点将当前路径分为AB两部分。其中,必然有(1)A部分剩余油量<0。(2)B部分剩余油量>0。

  • 所以,无论多少个站,都可以抽象为两个站点(A、B)。(1)从B站加满油出发,(2)开往A站,车加油,(3)再开回B站的过程。

重点:B剩余的油>=A缺少的总油。必然可以推出,B剩余的油>=A站点的每个子站点缺少的油。

问题可以抽象成两个站

B站 可以获得多余的油量 A站 要消耗更多油

class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        # 0       1   2    3     4 
        # -2     -2  -2    3     3
        start=0
        havgas=0
        co=[ga-cos for ga,cos in zip(gas,cost)]
        if sum(co)<0:
            return -1
        for index,c in enumerate(co):
            havgas+=c
            if havgas<0:
                start=index+1
                havgas=0
        return start
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值