记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
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