LeetCode 每日一题 2023/3/6-2023/3/12

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




3/6 1653. 使字符串平衡的最少删除次数

左侧是a右侧是b
对于某一位置 可以删除右边的a+左边的b
从头遍历 对于每个位置判断 在当前满足条件的操作次数

def minimumDeletions(s):
    """
    :type s: str
    :rtype: int
    """
    lb,ra = 0,s.count('a')
    ans = ra
    for c in s:
        if c=='a':
            ra -=1
        else:
            lb +=1
        ans = min(ans,ra+lb)
    return ans



3/7 1096. 花括号展开 II

递归解析
add用来生成两个set相加
如果遇到, 说明前后两部分相或
如果遇到{ 往后找到其对应的} 将这部分递归解析
如果前面为, 则将两部分相或 否则相加
其他符号则为表达式相连 根据前一个符号来决定相或 相加

def braceExpansionII(expression):
    """
    :type expression: str
    :rtype: List[str]
    """
    def add(a,b):
        ans = set()
        for i in a:
            for j in b:
                ans.add(i+j)
        return ans
    def check(ex):
        tmp = set()
        ans = set()
        loc = 0
        last = ","
        while loc<len(ex):
            if ex[loc]==",":
                ans = ans | tmp
                tmp =set()
                loc +=1
            elif ex[loc]=="{":
                cur = 1
                x = loc+1
                while cur>0:
                    if ex[x]=="{":
                        cur+=1
                    elif ex[x]=="}":
                        cur-=1
                    x+=1
                if last ==",":
                    tmp = tmp | check(ex[loc+1:x-1])
                else:
                    tmp = add(tmp,check(ex[loc+1:x-1]))
                loc = x
                last = "}"
            else:
                s = ""
                while loc<len(ex) and ex[loc]!="," and ex[loc]!="{":
                    s += ex[loc]
                    loc+=1
                if last==",":
                    tmp.add(s)
                else:
                    tmp = {i+s for i in tmp}
            last = ex[loc-1]
        return ans | tmp
    return sorted(check(expression))



3/8 剑指 Offer 47. 礼物的最大价值

每一格可由其左边或上边到达
从左上角开始 记录到达每个格子的最大价值

def maxValue(grid):
    """
    :type grid: List[List[int]]
    :rtype: int
    """
    m, n = len(grid), len(grid[0])
    for j in range(1, n): # 初始化第一行
        grid[0][j] += grid[0][j - 1]
    for i in range(1, m): # 初始化第一列
        grid[i][0] += grid[i - 1][0]
    for i in range(1, m):
        for j in range(1, n):
            grid[i][j] += max(grid[i][j - 1], grid[i - 1][j])
    return grid[-1][-1]



3/9 2379. 得到 K 个黑块的最少涂色次数

滑动窗口 长度为k
往右移动记录窗口内白色的数量

def minimumRecolors(blocks, k):
    """
    :type blocks: str
    :type k: int
    :rtype: int
    """
    wnum = 0
    for i in range(k):
        if blocks[i]=='W':
            wnum +=1
    ans = wnum
    for i in range(k,len(blocks)):
        if blocks[i]=='W':
            wnum +=1
        if blocks[i-k]=='W':
            wnum -=1
        print(i-k,i,wnum)
        ans = min(ans,wnum)
    return ans



3/10 1590. 使数组和能被 P 整除

value记录总和除以P的余数
mem[x]从头遍历记录余数x最近的位置
寻找当前位置为结尾能够取到value的最短长度

def minSubarray(nums, p):
    """
    :type nums: List[int]
    :type p: int
    :rtype: int
    """
    value = sum(nums)%p
    if value==0:
        return 0
    mem = {}
    mem[0]=-1
    cur = 0
    ans = len(nums)
    for i,v in enumerate(nums):
        cur = (cur+v)%p
        if (cur-value)%p in mem:
            ans = min(ans,i-mem[(cur-value)%p])
        mem[cur] = i
    if ans<len(nums):
        return ans
    return -1



3/11 面试题 17.05. 字母与数字

tag数组记录状态
遍历数组 遇到字母+1 遇到数字-1
如果当前位置tag=0 说明数组到这里字母与数字个数相同
endmap记录tag出现在数组中最靠后的位置
从后往前遍历tag数组
对于位置i为起点的满足条件的数组 及找到tag[i]最后出现的位置=endmap[tag[i]]

def findLongestSubarray(array):
    """
    :type array: List[str]
    :rtype: List[str]
    """
    curr = 0
    tag = [0]
    for c in array:
        if c.isdigit():
            curr -=1
        else:
            curr +=1
        tag.append(curr)
    endmap = {}
    maxlen = 0
    ans = []
    n = len(tag)
    for i in range(n-1,-1,-1):
        v = tag[i]
        if v in endmap:
            if maxlen<=(endmap[v]-i):
                maxlen = endmap[v]-i
                ans = array[i:endmap[v]]
        else:
            endmap[v] = i
    return ans



3/12 1617. 统计子树中城市之间最大距离

节点数不大于15个 可以枚举所有子树
使用二进制来表示一个子树 1表示节点在子树内 0表示节点不在子树内
在一个子树中 使用BFS先找到子树一个端点
再从端点出发BFS求出子树两节点间的最大距离

def countSubgraphsForEachDiameter(n, edges):
    """
    :type n: int
    :type edges: List[List[int]]
    :rtype: List[int]
    """
    from collections import defaultdict
    g = defaultdict(list)
    for i,j in edges:
        i-=1
        j-=1
        g[i].append(j)
        g[j].append(i)
    ans = [0]*(n-1)
    global msk,nxt
    nxt = 0
    def bfs(node):
        global msk,nxt
        msk ^=1<<node
        l = [node]
        d = -1
        while l:
            tmp = []
            d +=1
            for v in l:
                nxt = v
                for nod in g[v]:
                    if msk>>nod &1:
                        msk ^= 1<<nod
                        tmp.append(nod)
            l = tmp[:]
        return d
                    
    for mask in range(1,1<<n):
        if mask &(mask-1)==0:
            continue
        msk = mask
        cur = msk.bit_length()-1
        bfs(cur)
        if msk == 0:
            msk=mask
            mx = bfs(nxt)
            ans[mx-1]+=1
    return ans
        



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值