当前位置: 首页 > article >正文

LeetCode 每日一题 2024/10/28-2024/11/3

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


目录

      • 10/28 685. 冗余连接 II
      • 10/29 3211. 生成不含相邻零的二进制字符串
      • 10/30 3216. 交换后字典序最小的字符串
      • 10/31 3165. 不包含相邻元素的子序列的最大和
      • 11/1 3259. 超级饮料的最大强化能量
      • 11/2 3226. 使两个整数相等的位更改次数
      • 11/3638. 大礼包


10/28 685. 冗余连接 II

check用来检查是否满足
1.入度不能有大于1的
2.不能存在圈
先将所有点的父节点取出,如果存在有两个父节点 那么说明这个节点需要取出一条边 遍历后check是否正确
若正确 将结果暂存ret
判断ret,
若ret内有多个 则取出位置最靠后的作为结果
若ret==0:
所有节点入度都正常 说明存在圈 从后往前去除一个点 check是否正常 若正常则答案为这个点

def findRedundantDirectedConnection(edges):
    """
    :type edges: List[List[int]]
    :rtype: List[int]
    
    """
    def find(p,x):
        while p[x] != x:
            p[x] = p[p[x]]
            x = p[x]
        return p[x]
            # 判断给定的图是不是有圈
    def cycle(graph):
        p = {}
        for a, b in graph:
           
            p.setdefault(a, a)
            p.setdefault(b, b)
            pa, pb = find(p, a), find(p, b)
            print([a,b],p,pa,pb)
            if pa == pb: 
                return(True)
            else:
                p[pa] = p[pb]
    dic={}
    ans=[]
    ret =[]
    def check(l):
        #入度不能大于1
        endpoint = [y for x,y in l]
        if len(endpoint)!=len(set(endpoint)):
            return False

        def find(p,x):
            while p[x] != x:
                p[x] = p[p[x]]
                x = p[x]
            return p[x]

        # 判断给定的图是不是有圈
        def cycle(graph):
            p = {}
            for a, b in graph:
                p.setdefault(a, a)
                p.setdefault(b, b)
                pa, pb = find(p, a), find(p, b)
                if pa == pb: 
                    return(True)
                else:
                    p[pa] = p[pb]
                    
        if cycle(l):
            return False
            
        return True
    
    for v in edges:
        top = v[0]
        end = v[1]
        dic.setdefault(end,[])
        dic[end].append(top)
            
    for k in dic.keys():
        if len(dic[k])>1:
            for v in dic[k]:
                ori = edges[:]
                tmp=[v,k]
                ori.pop(ori.index(tmp))
                if check(ori):
                    ret.append(tmp)
    
    if len(ret)==0:
        for i in range(len(edges)-1,-1,-1):
            ori = edges[:]
            ori.pop(i)
            if check(ori):
                ans = edges[i]
                break
    else:
        pos = -1
        for i in ret:
            if edges.index(i)>pos:
                pos = edges.index(i)
                ans = i    
    
    return ans



10/29 3211. 生成不含相邻零的二进制字符串

所有长度为2的子字符串至少有一个1 说明不存在连续的两个0
将二进制按位取反为x 判断不存在连续两个1
如果x&(x>>1)=0 说明x没有连续的两个1

def validStrings(n):
    """
    :type n: int
    :rtype: List[str]
    """
    ans = []
    mask = (1<<n)-1
    for i in range(1<<n):
        t = mask^i
        if (t>>1 & t)==0:
            ans.append(f"{i:0{n}b}")
    return ans



10/30 3216. 交换后字典序最小的字符串

从前往后寻找
找到首次出现满足前面数字比后面大的就交换

def getSmallestString(s):
    """
    :type s: str
    :rtype: str
    """
    l=list(s)
    n=len(s)
    for i in range(n-1):
        if int(l[i])%2==int(l[i+1])%2 and l[i]>l[i+1]:
            l[i],l[i+1]=l[i+1],l[i]
            break
    return ''.join(l)



10/31 3165. 不包含相邻元素的子序列的最大和

将数组分为两段 每一段的首尾都有不选 或 可选两种情况
一共就有四种情况
00:首不选 尾不选
01:首不选 尾可选
10:首可选 尾不选
11:首可选 尾可选
将某数组x分为前后a,b两段 分别讨论四种情况
f(x)为x数组不相邻子序列最大和
f00(x) = max(f01(a)+f00(b),f00(a)+f10(b))
f01(x) = max(f00(a)+f11(b),f01(a)+f01(b))
f10(x) = max(f10(a)+f10(b),f11(a)+f00(b))
f11(x) = max(f10(a)+f11(b),f11(a)+f01(b))
用线段树来实现单点的修改 每个节点维护对应区间f(X)

def maximumSumSubsequence(nums, queries):
    """
    :type nums: List[int]
    :type queries: List[List[int]]
    :rtype: int
    """
    MOD=10**9+7
    n=len(nums)
    tr = [[0]*4 for _ in range(2<<n.bit_length())]
    
    def maxv(a,b):
        return b if b>a else a
    
    def merg(k):
        a,b = tr[k*2],tr[k*2+1]
        tr[k][0] = max(a[0]+b[2],a[1]+b[0])
        tr[k][1] = max(a[0]+b[3],a[1]+b[1])
        tr[k][2] = max(a[2]+b[2],a[3]+b[0])
        tr[k][3] = max(a[2]+b[3],a[3]+b[1])
    def build(k,l,r):
        if l==r:
            tr[k][3]=maxv(nums[l],0)
            return
        m=(l+r)//2
        build(k*2,l,m)
        build(k*2+1,m+1,r)
        merg(k)
    
    def change(k,l,r,i,val):
        if l==r:
            tr[k][3]=max(val,0)
            return
        m=(l+r)//2
        if i<=m:
            change(k*2,l,m,i,val)
        else:
            change(k*2+1,m+1,r,i,val)
        merg(k)
    
    build(1,0,n-1)
    ans = 0
    for i,val in queries:
        change(1,0,n-1,i,val)
        ans = (ans+tr[1][3])%MOD
    return ans



11/1 3259. 超级饮料的最大强化能量

动态规划 f[i][0/1]代表第i步喝A/B获得的最大值

def maxEnergyBoost(energyDrinkA, energyDrinkB):
    """
    :type energyDrinkA: List[int]
    :type energyDrinkB: List[int]
    :rtype: int
    """
    n=len(energyDrinkA)
    f = [[0,0] for _ in range(n+1)]
    for i in range(1,n+1):
        f[i][0] = f[i-1][0]+energyDrinkA[i-1]
        f[i][1] = f[i-1][1]+energyDrinkB[i-1]
        if i>1:
            f[i][0] = max(f[i][0],f[i-2][1]+energyDrinkA[i-1])
            f[i][1] = max(f[i][1],f[i-2][0]+energyDrinkB[i-1])
    return max(f[n][0],f[n][1])



11/2 3226. 使两个整数相等的位更改次数

按位判断

def minChanges(n, k):
    """
    :type n: int
    :type k: int
    :rtype: int
    """
    ans = 0
    while n>0 or k>0:
        if (n&1)==0 and (k&1)==1:
            return -1
        if (n&1)==1 and (k&1)==0:
            ans+=1
        n>>=1
        k>>=1
    return ans



11/3638. 大礼包

过滤掉不需要的套餐 保留有用套餐
dfs 遍历选取每一种套餐的情况
算出不买套餐的价格base
如果买套餐实惠则替换价格

def shoppingOffers(price, special, needs):
    """
    :type price: List[int]
    :type special: List[List[int]]
    :type needs: List[int]
    :rtype: int
    """
    n = len(price)
    
    fsp = []
    for sp in special:
        if sum(sp[i]*price[i] for i in range(n))>sp[n]:
            fsp.append(sp)
    
    def dfs(curneed):
        base = sum(curneed[i]*price[i] for i in range(n))
        for cursp in fsp:
            p = cursp[n]
            netneed = []
            for i in range(n):
                if cursp[i]>curneed[i]:
                    break
                netneed.append(curneed[i]-cursp[i])
            if len(netneed)==n:
                base = min(base,dfs(netneed)+p)
        return base
    return dfs(needs)




http://www.kler.cn/a/377053.html

相关文章:

  • 用Fiddler如何对Jmeter的请求进行抓包
  • python的json库的基本应用
  • 富格林:可信措施提升追损效率
  • 光学基础知识(2)体全息光存储技术
  • 终于弄懂了Python中列表的定义
  • springboot 自动装配和bean注入原理及实现
  • 贪心算法---java---黑马
  • 【ChatGPT】让ChatGPT根据固定模板生成报告或文档
  • 七、Go语言快速入门之函数func
  • 智能呼叫中心详细介绍
  • Android——显式/隐式Intent
  • Air780EP之RC522开发板,你了解吗?
  • 重磅新品丨Fortinet 发布 Lacework FortiCNAPP,强化云原生应用安全
  • 新建Flutter工程
  • RS485接口EMC电路设计方案
  • Kafka-生产者源码分析
  • 【深度学习基础】常用图像卷积核类型
  • 关于我的编程语言——C/C++——第四篇(深入1)
  • 统信UOS设备驱动开发-核心模块
  • uln2003驱动28BYJ-48步进电机