LeetCode 每日一题 2024/8/19-2024/8/25

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




8/19 552. 学生出勤记录 II

状态转移 dp
缺勤最多只能1次
所以可以分为a,p 分别代表缺勤一次 未缺勤
连续迟到最多可以2次 所以分为0,1,2 代表连续迟到天数
所以一共有六种状态a0,a1,a2,p0,p1,p2
p0可以由p0,p1,p2 +P转变
p1只能由p0 +L转变
p2只能由p1 +L转变
a0可以由p0,p1,p2 +A 或者a0,a1,a2 +P转变
a1只能由a0 +L转变
a2只能由a1 +L转变
循环n次将六种状态累加得到答案

def checkRecord(n):
    """
    :type n: int
    :rtype: int
    """
    MOD=10**9+7
    p0,p1,p2 = 1,0,0
    a0,a1,a2 = 0,0,0
    for i in range(n):
        t0,t1,t2 = p0,p1,p2
        p0,p1,p2 = (p0+p1+p2)%MOD,p0,p1
        a0,a1,a2 = (a0+a1+a2+t0+t1+t2)%MOD,a0,a1
    ans = (p0+p1+p2+a0+a1+a2)%MOD
    return ans



8/20 3128. 直角三角形

枚举两条直角边的交点 构成直角三角形 将这个点所在行的点与所在列的点一一匹配
假设所在行有row个点 所在列有col个点 那么以这个点为转折点的直角三角形有(row-1)*(col-1)个

def numberOfRightTriangles(grid):
    """
    :type grid: List[List[int]]
    :rtype: int
    """
    n=len(grid)
    m=len(grid[0])
    col =[0]*m
    for j in range(m):
        for i in range(n):
            col[j]+=grid[i][j]
    ans = 0
    for i in range(n):
        row = sum(grid[i])
        for j in range(m):
            if grid[i][j]==1:
                ans +=(row-1)*(col[j]-1)
    return  ans



8/21 3007. 价值和小于等于 K 的最大数字

num越大 价值和必定也越大
二分查找

def findMaximumNumber(k, x):
    """
    :type k: int
    :type x: int
    :rtype: int
    """
    def bitprice(x,num):
        p=1<<x
        ans = (p//2)*(num//p)
        if num%p>=(p//2):
            ans+=num%p-(p//2-1)
        return ans
    def getprice(x,num):
        ans = 0
        n = len(bin(num))-2
        for i in range(x,n+1,x):
            ans += bitprice(i,num)
        return ans
    l,r=1,(k+1)<<x
    while l<r:
        mid = (l+r+1)//2
        if getprice(x,mid)>k:
            r = mid-1
        else:
            l = mid
    return l



8/22 3133. 数组最后一个元素的最小值

元素的按位AND运算结果为x说明最小值就是x 如果最小值小于x 那么按位与必定小于x
找到x所有为0的位置 这些位置从小到大为 0,1,2,3…n-1
例如10101 中的2个00 从小到大00 01 10 11
即为10101 10110 11101 11111
如果继续增大可以看做是00…0010101
可以看做将n的二进制依次填入x中0的位置

def minEnd(n, x):
    """
    :type n: int
    :type x: int
    :rtype: int
    """
    ans = x
    m = n-1
    j = 0
    for i in range(53):
        if ((ans>>i)&1)==0:
            if ((m>>j)&1)!=0:
                ans |=(1<<i)
            j+=1
    return ans



8/23 3145. 大数组元素的乘积

cv 看题解吧 -.-
https://leetcode.cn/problems/find-products-of-elements-of-big-array/solutions/2774549/olog-shi-tian-fa-pythonjavacgo-by-endles-w2l4/?envType=daily-question&envId=2024-08-23

def findProductsOfElements(queries):
    """
    :type queries: List[List[int]]
    :rtype: List[int]
    """
    def func(k):
        ans = 0
        n = 0
        cnt = 0
        sumi = 0
        for i in range((k+1).bit_length()-1,0,-1):
            c = (cnt<<i)+(i<<(i-1))
            if c<=k:
                k-=c
                ans +=(sumi<<i)+((i*(i-1)//2)<<(i-1))
                sumi+=i
                cnt+=1
                n|=1<<i
        if cnt<=k:
            k-=cnt
            ans +=sumi
            n|=1
        for _ in range(k):
            lb = n&(-n)
            ans += lb.bit_length()-1
            n ^=lb
        return ans
    return [pow(2,func(r+1)-func(l),mod) for l,r,mod in queries]



8/24 3146. 两个字符串的排列差

遍历一次s 记录每个字符位置
遍历一次t 计算位置的差

def findPermutationDifference(s, t):
    """
    :type s: str
    :type t: str
    :rtype: int
    """
    m={}
    for i,c in enumerate(s):
        m[c]=i
    ans = 0
    for i,c in enumerate(t):
        ans += abs(m[c]-i)
    return ans
        



8/25





  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值