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

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


目录

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

10/28 685. 冗余连接 II

check用来检查是否满足

1.入度不能有大于1的

2.不能存在圈

先将所有点的父节点取出,如果存在有两个父节点 那么说明这个节点需要取出一条边 遍历后check是否正确

若正确 将结果暂存ret

判断ret,

若ret内有多个 则取出位置最靠后的作为结果

若ret==0:

所有节点入度都正常 说明存在圈 从后往前去除一个点 check是否正常 若正常则答案为这个点

python 复制代码
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

python 复制代码
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. 交换后字典序最小的字符串

从前往后寻找

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

python 复制代码
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)

python 复制代码
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获得的最大值

python 复制代码
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. 使两个整数相等的位更改次数

按位判断

python 复制代码
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

如果买套餐实惠则替换价格

python 复制代码
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)

相关推荐
梧桐树04291 小时前
python常用内建模块:collections
python
Dream_Snowar1 小时前
速通Python 第三节
开发语言·python
XH华1 小时前
初识C语言之二维数组(下)
c语言·算法
南宫生2 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
不想当程序猿_2 小时前
【蓝桥杯每日一题】求和——前缀和
算法·前缀和·蓝桥杯
落魄君子2 小时前
GA-BP分类-遗传算法(Genetic Algorithm)和反向传播算法(Backpropagation)
算法·分类·数据挖掘
菜鸡中的奋斗鸡→挣扎鸡2 小时前
滑动窗口 + 算法复习
数据结构·算法
蓝天星空2 小时前
Python调用open ai接口
人工智能·python
Lenyiin2 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin
jasmine s2 小时前
Pandas
开发语言·python