LeetCode 每日一题 2022/6/20-2022/6/26

记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步




6/20 715. Range 模块

线段树 动态开点+懒标记
v代表是添加或者删除 val表示当前点是否在区间内

MAXNUM = int(1e9+7)
class Node:
    def __init__(self):
        self.left = None
        self.right = None
        self.val = False
        self.add = False
        
class RangeModule(object):

    def __init__(self):
        self.root = Node()
        
    def update(self,node,lc,rc,l,r,v):
        if l<=lc and r>=rc:
            node.val = v
            node.add = True
            return
        self.pushdown(node)
        mid = (lc+rc)>>1
        if l<=mid:
            self.update(node.left,lc,mid,l,r,v)
        if r>mid:
            self.update(node.right,mid+1,rc,l,r,v)
        self.pushup(node)
    
    def query(self,node,lc,rc,l,r):
        if l<=lc and r>=rc:
            return node.val
        self.pushdown(node)
        mid = (lc+rc)>>1
        ans = True
        if l<=mid:
            ans = ans and self.query(node.left,lc,mid,l,r)
        if r>mid:
            ans = ans and self.query(node.right,mid+1,rc,l,r)
        return ans
    def pushdown(self,node):
        if not node.left :
            node.left = Node()
        if not node.right:
            node.right = Node()
        if not node.add:
            return
        node.left.val = node.val
        node.right.val = node.val
        node.left.add = True
        node.right.add = True
        node.add = False
    def pushup(self,node):
        node.val = node.left.val  and node.right.val
            

    def addRange(self, left, right):
        """
        :type left: int
        :type right: int
        :rtype: None
        """
        self.update(self.root,1,MAXNUM,left,right-1,True)


    def queryRange(self, left, right):
        """
        :type left: int
        :type right: int
        :rtype: bool
        """
        return self.query(self.root,1,MAXNUM,left,right-1)


    def removeRange(self, left, right):
        """
        :type left: int
        :type right: int
        :rtype: None
        """
        self.update(self.root,1,MAXNUM,left,right-1,False)





6/21 1108. IP 地址无效化

根据.切割字符串 加入[.]

def defangIPaddr(address):
    """
    :type address: str
    :rtype: str
    """
    return "[.]".join(address.split("."))



6/22 513. 找树左下角的值

dfs深搜
find 返回当前节点为根节点的子树 最深深度及最左边的值

def findBottomLeftValue(root):
    """
    :type root: TreeNode
    :rtype: int
    """
    def find(node,deep):
        val,dep = node.val,deep
        valr,depr = node.val,deep
        if node.left:
            val,dep = find(node.left,deep+1)
        if node.right:
            valr,depr = find(node.right,deep+1)
        if depr>dep:
            val,dep = valr,depr
        return val,dep
    val,_=find(root,0)
    return val



6/23 30. 串联所有单词的子串

每个单词长度一致=n
从0~n-1位置开始分别考虑
m为需要出现的单词数量
间隔n为一个单词 滑动窗口记录出现单词数目
每一次右侧位置向右取一个单词
如果出现不存在单词
则将整个窗口移到这个单词右侧重新开始计算
如果所有需要出现的单词都已经出现
则记录当前起始位置
将左侧窗口向右移动一个单词继续考虑

def findSubstring(s, words):
    """
    :type s: str
    :type words: List[str]
    :rtype: List[int]
    """
    n = len(words[0])
    m = {}
    for word in words:
        m[word] = m.get(word,0)+1
    num = len(words)
    ans = []
    for i in range(n):
        left = i
        right = i
        tmpm = m.copy()
        while right+n<=len(s):
            word = s[right:right+n]
            if word not in m:
                left = right +n
                right = left
                tmpm = m.copy()
            else:
                tmpm[word]-=1
                right += n
            if right - left == num*n:
                if all([v==0 for v in tmpm.values()]):
                    ans.append(left)
                word = s[left:left+n]
                left = left+n
                tmpm[word] +=1  
                
    return ans



6/24 515. 在每个树行中找最大值

BFS 广搜每一层 记录最大值

class TreeNode(object):
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
def largestValues(root):
    """
    :type root: TreeNode
    :rtype: List[int]
    """
    ans = []
    l = [root]
    while l:
        tmp = []
        val = 0
        for node in l:
            val = max(val,node.val)
            if node.left:
                tmp.append(node.left)
            if node.right:
                tmp.append(node.right)
        ans.append(val)
        l = tmp
    return ans



6/25 剑指 Offer II 091. 粉刷房子

动态规划
r[x],b[x],g[x]分别代表从起始开始到当前房子x,x被刷成红色/蓝色/绿色时最小的话费
r[x] = min(b[x-1],g[x-1])+cost[x][red]
其他亦然
最终比较最后位置三个结果取最小即可


def minCost(costs):
    """
    :type costs: List[List[int]]
    :rtype: int
    """
    r,b,g = costs[0][0],costs[0][1],costs[0][2]
    for cr,cb,cg in costs[1:]:
        r,b,g = min(b,g)+cr,min(r,g)+cb,min(r,b)+cg
    return min(r,b,g)


6/26 710. 黑名单中的随机数

能够随机到的数 一共有n-len(blacklist)个
在这个范围内随机
这个范围内的黑名单的数
与剩余的len(blacklist)个数中的可随机数映射

import random
class Solution(object):

    def __init__(self, n, blacklist):
        """
        :type n: int
        :type blacklist: List[int]
        """
        self.s = n-len(blacklist)
        self.m = {}
        b = set(blacklist)
        start = self.s-1
        for i in blacklist:
            if i<self.s:
                start +=1
                while start in b:
                    start+=1
                self.m[i] = start

    def pick(self):
        """
        :rtype: int
        """
        rd = random.randint(0,self.s-1)
        if rd in self.m:
            rd = self.m[rd]
        return rd



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值