LeetCode 每日一题 2025/7/21-2025/7/27

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




7/21 1957. 删除字符使字符串变好

依次判断当前字符是否可以加入到答案中

def makeFancyString(s):
    """
    :type s: str
    :rtype: str
    """
    ans=[]
    for c in s:
        if len(ans)>=2 and ans[-1]==ans[-2]==c:
            continue
        ans.append(c)
    return ''.join(ans)
    



7/22 1695. 删除子数组的最大得分

即找到和最大的不含重复数字的子数组

def maximumUniqueSubarray(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    ans=0
    cur=0
    s=set()
    l,r=0,0
    while r<len(nums):
        while nums[r] in s:
            num=nums[l]
            cur-=num
            s.remove(num)
            l+=1
        num=nums[r]
        cur+=num
        ans=max(ans,cur)
        s.add(num)
        r+=1
    return ans



7/23 1717. 删除子字符串的最大得分

假设ab分数比ba高 如果不是则调换
将字符串内除了ab之外的字符看作分割点
对于只包含ab的字符串每次操作删除一个a,一个b 操作次数固定
所以先删除分数大的ab 可以得到更高的分数
numa,numb记录当前子字符串内a,b的个数
遍历当前字符c
如果c=a 先删除ab所以暂时不删除a numa+1
如果c=b 并且numa>0 可以删除ab并+x 否则numb+1
如果c是其他字符 则当前为分割点
对于子字符串内还有numa个a numb个b 删除ba 有min(numa,numb)个


def maximumGain(s, x, y):
    """
    :type s: str
    :type x: int
    :type y: int
    :rtype: int
    """
    a,b="a","b"
    if x<y:
        a,b=b,a
        x,y=y,x
        
    ans=0
    numa,numb=0,0
    for c in s:
        if c==a:
            numa+=1
        elif c==b:
            if numa>0:
                ans+=x
                numa-=1
            else:
                numb+=1
        else:
            ans+=min(numa,numb)*y
            numa,numb=0,0
    ans+=min(numa,numb)*y
    return ans


7/24 2322. 从树中删除边的最小分数

将0看作是根节点
删除两条边x1-y1,x2-y2三种情况
1.删除两条边在同一子树内 y1为x2的祖先
2.删除两条边在同一子树内 y2为x1的祖先
3.删除两条边属于不想交两个子树
https://leetcode.cn/problems/minimum-score-after-removals-on-a-tree/solutions/1625899/dfs-shi-jian-chuo-chu-li-shu-shang-wen-t-x1kk/?envType=daily-question&envId=2025-07-24

def minimumScore(nums, edges):
    """
    :type nums: List[int]
    :type edges: List[List[int]]
    :rtype: int
    """
    n=len(nums)
    g=[[]for _ in range(n)]
    for x,y in edges:
        g[x].append(y)
        g[y].append(x)
    
    xor,in_,out=[0]*n,[0]*n,[0]*n
    global clc
    clc=0
    def dfs(x,fa):
        global clc
        clc+=1
        in_[x]=clc
        xor[x]=nums[x]
        for y in g[x]:
            if y!=fa:
                dfs(y,x)
                xor[x]^=xor[y]
        out[x]=clc
    dfs(0,-1)
    
    def isfa(x,y):
        return in_[x]<in_[y]<=out[x]
    ans=float("inf")
    for x in range(2,n):
        for y in range(1,x):
            if isfa(x, y):
                a,b,c=xor[y],xor[x]^xor[y],xor[0]^xor[x]
            elif isfa(y, x):
                a,b,c=xor[x],xor[x]^xor[y],xor[0]^xor[y]
            else:
                a,b,c=xor[x],xor[y],xor[0]^xor[x]^xor[y]
            ans=min(ans,max(a,b,c)-min(a,b,c))
            if ans==0:
                return ans
    return ans



7/25 3487. 删除后的最大子数组元素和

可以看做删除到最后 只剩下一个满足条件的子数组
不存在重复数值和负数
去重 排序
从大往小加直至遇到负数
因为至少要存在一个数 不论正负
所以先将最大的那个加入答案

def maxSum(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    s=sorted(list(set(nums)))
    ans=s[-1]
    for num in s[-2::-1]:
        if num<0:
            break
        ans+=num
    return ans



7/26 3480. 删除一个冲突对后最大子数组数目

确定左端点i, 如果一个冲突对a,b
如果a<i 那么右端点j取任何值都不会包含a,b
如果a>=i 那么右端点j<min(b,n+1)
使用bm1,bm2记录同一个a 最小b和次小b
使用delcnt[ib1]记录删除b1后 增加的个数min(min(b2,bm2[ib1]),n+1)-min(b1,n+1)

def maxSubarrays(n, conflictingPairs):
    """
    :type n: int
    :type conflictingPairs: List[List[int]]
    :rtype: int
    """
    bm1,bm2=[2**31-1]*(n+1),[2**31-1]*(n+1)
    
    for p in conflictingPairs:
        a,b=min(p[0],p[1]),max(p[0],p[1])
        if bm1[a]>b:
            bm2[a]=bm1[a]
            bm1[a]=b
        elif bm2[a]>b:
            bm2[a]=b
            
    ans=0
    ib1=n
    b2=2**31-1
    delcnt=[0]*(n+1)
    for i in range(n,0,-1):
        if bm1[ib1]>bm1[i]:
            b2=min(b2,bm1[ib1])
            ib1=i
        else:
            b2=min(b2,bm1[i])
        ans+=min(bm1[ib1],n+1)-i
        delcnt[ib1]+=min(min(b2,bm2[ib1]),n+1)-min(bm1[ib1],n+1)
    return ans+max(delcnt)



7/27 2210. 统计数组中峰和谷的数量

去除相连重复数值 再判断峰谷

def countHillValley(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    k=1
    for i in range(1,len(nums)):
        if nums[i]!=nums[i-1]:
            nums[k]=nums[i]
            k+=1
    ans=0
    
    for i in range(1,k-1):
        if (nums[i-1]<nums[i]) == (nums[i]>nums[i+1]):
            ans+=1
    return ans
        



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值