LeetCode 每日一题 2023/6/5-2023/6/11

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




6/5 2460. 对数组执行操作

依次执行

def applyOperations(nums):
    """
    :type nums: List[int]
    :rtype: List[int]
    """
    n = len(nums)
    for i in range(n-1):
        if nums[i]==nums[i+1]:
            nums[i]=2*nums[i]
            nums[i+1]=0
    ans = [0]*n
    loc = 0
    for i in range(n):
        if nums[i]>0:
            ans[loc]=nums[i]
            loc+=1
    return ans



6/6 2352. 相等行列对

将所有行的状态保存
遍历所有列 查看该状态有几个行存在

def equalPairs(grid):
    """
    :type grid: List[List[int]]
    :rtype: int
    """
    from collections import defaultdict
    n = len(grid)
    line = defaultdict(int)
    for l in grid:
        v = tuple(l)
        line[v] +=1
    ans = 0
    for i in range(n):
        v = tuple([grid[x][i] for x in range(n)])
        ans += line[v]
    return ans




6/7 2611. 老鼠和奶酪

计算每一块奶酪被1号老鼠吃比2号老鼠吃要多的得分
选择得分差值为正最高的k个

def miceAndCheese(reward1, reward2, k):
    """
    :type reward1: List[int]
    :type reward2: List[int]
    :type k: int
    :rtype: int
    """
    n = len(reward1)
    l=[(reward1[i]-reward2[i],i) for i in range(n)]
    l.sort(reverse=True)
    s = sum(reward2)
    for i in range(k):
        s += l[i][0]
    return s



6/8 1240. 铺瓷砖

filled[i]使用m位二进制 来表示第i行被覆盖的状态
遍历每个位置i,j 未被覆盖则找到能够添加的最大边长mx
遍历每种可能情况1~mx

def tilingRectangle(n, m):
    """
    :type n: int
    :type m: int
    :rtype: int
    """
    global ans
    filled = [0]*n
    ans = n*m
    def dfs(i,j,num):
        global ans
        if j==m:
            i,j=i+1,0
        if i==n:
            ans = num
            return
        if filled[i]>>j & 1:
            dfs(i,j+1,num)
        elif num+1<ans:
            r,c=0,0
            for k in range(i,n):
                if filled[k]>>j&1:
                    break
                r+=1
            for k in range(j,m):
                if filled[i]>>k&1:
                    break
                c+=1
            mx = min(c,r)
            for w in range(1,mx+1):
                for k in range(w):
                    filled[i+w-1] |= 1<<(j+k)
                    filled[i+k] |= 1<<(j+w-1)
                dfs(i,j+w,num+1)
            for x in range(i,i+mx):
                for y in range(j,j+mx):
                    filled[x] ^= 1<<y
    dfs(0,0,0)
    return ans



6/9 2699. 修改图中的边权

dijkstra
如果未知路径全为1 最短路径任然大于target则无解
如果未知路径全为无穷 最短路径任然小于target则无解
进行两次搜索
https://leetcode.cn/problems/modify-graph-edge-weights/solutions/2278296/xiang-xi-fen-xi-liang-ci-dijkstrachou-mi-gv1m/

def modifiedGraphEdges(n, edges, source, destination, target):
    """
    :type n: int
    :type edges: List[List[int]]
    :type source: int
    :type destination: int
    :type target: int
    :rtype: List[List[int]]
    """
    g = [[] for _ in range(n)]
    for i,(x,y,_) in enumerate(edges):
        g[x].append((y,i))
        g[y].append((x,i))
    
    dis = [[float("inf"),float("inf")] for _ in range(n)]
    dis[source]=[0,0]
    
    def dijkstra(k):
        mem = [False]*n
        while True:
            x = -1
            for y,(b,d) in enumerate(zip(mem,dis)):
                if not b and (x<0 or d[k]<dis[x][k]):
                    x = y
            if x==destination:
                return
            mem[x] = True
            for y,ind in g[x]:
                wt = edges[ind][2]
                if wt ==-1:
                    wt=1
                if k==1 and edges[ind][2]==-1:
                    w = delta+dis[y][0]-dis[x][1]
                    if w>wt:
                        edges[ind][2] = wt = w
                dis[y][k] = min(dis[y][k],dis[x][k]+wt)
    dijkstra(0)
    delta = target - dis[destination][0]
    if delta<0:
        return []
    dijkstra(1)
    if dis[destination][1]<target:
        return []
    
    for e in edges:
        if e[2]==-1:
            e[2]=1
    return edges



6/10 1170. 比较字符串最小字母出现频次

单词长度最大为10 所以f(s)最大为10
l[i] 记录 f(s)为i的个数 并后缀和统计
即l[i]为f(s)大于i的个数

def numSmallerByFrequency(queries, words):
    """
    :type queries: List[str]
    :type words: List[str]
    :rtype: List[int]
    """
    def check(s):
        ans = 0
        cur = 'z'
        for c in s:
            if c<cur:
                cur = c
                ans = 1
            elif c==cur:
                ans +=1
        return ans
    l = [0]*12
    for w in words:
        v = check(w)
        l[v]+=1
    
    for i in range(9,0,-1):
        l[i]+=l[i+1]
    ans = []
    for q in queries:
        v = check(q)
        ans.append(l[v+1])
    return ans



6/11 1171. 从链表中删去总和值为零的连续节点

遍历一次链表 pre为前缀和
map存储前缀和所对应的节点 如果存在两个相同的前缀和
说明两个节点间的总和为0 map中后面的节点覆盖前面的节点位置
第二次按照前缀和对应的节点连接

class ListNode(object):
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
def removeZeroSumSublists(head):
    """
    :type head: ListNode
    :rtype: ListNode
    """
    m = {}
    start = ListNode(0)
    pre = 0
    m[0] = start
    start.next= head
    while head:
        pre += head.val
        m[pre] = head
        head = head.next
    head = start
    pre = 0
    while head:
        pre += head.val
        head.next = m[pre].next
        head = head.next
    return start.next



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值