LeetCode 每日一题 2025/4/28-2025/5/4
记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
- 4/28 2302. 统计得分小于 K 的子数组数目
- 4/29 2962. 统计最大元素出现至少 K 次的子数组
- 4/30 1295. 统计位数为偶数的数字
- 5/1 2071. 你可以安排的最多任务数目
- 5/2 838. 推多米诺
- 5/3 1007. 行相等的最少多米诺旋转
- 5/4 1128. 等价多米诺骨牌对的数量
4/28 2302. 统计得分小于 K 的子数组数目
滑动窗口 固定右侧端点r
找到左侧端点l 使得[l,r]第一次满足条件
那么以l右侧的位置为左端点必定满足
def countSubarrays(nums, k):""":type nums: List[int]:type k: int:rtype: int"""n=len(nums)ans=0total=0l=0for r in range(n):total+=nums[r]while l<=r and total*(r-l+1)>=k:total-=nums[l]l+=1ans+=r-l+1return ans
4/29 2962. 统计最大元素出现至少 K 次的子数组
遍历记录最大元素出现的位置 ind
对于最大元素位置i1 在(i0,i1]间的所有位置都需要到ik为止才能满足
此时有(i1-i0)*(n-ik)个子数组
def countSubarrays(nums, k):""":type nums: List[int]:type k: int:rtype: int"""n=len(nums)maxv=max(nums)ind=[-1]for i in range(n):if nums[i]==maxv:ind.append(i)l,r=1,kans=0while r<len(ind):ans+=(ind[l]-ind[l-1])*(n-ind[r])l+=1r+=1return ans
4/30 1295. 统计位数为偶数的数字
依次判断
def findNumbers(nums):""":type nums: List[int]:rtype: int"""def check(num):b = 0while num>0:num=num//10b+=1return b%2==0ans = 0for num in nums:if check(num):ans+=1return ans
5/1 2071. 你可以安排的最多任务数目
假设完成k个任务 选择k个值最小的任务 和k个力量最大的工人
二分来找到最大的k
check(mid)用来判断mid个是否满足
def maxTaskAssign(tasks, workers, pills, strength):""":type tasks: List[int]:type workers: List[int]:type pills: int:type strength: int:rtype: int"""from sortedcontainers import SortedListn=len(tasks)m=len(workers)tasks.sort()workers.sort()def check(mid):p=pillswk=SortedList(workers[m-mid:])for i in range(mid-1,-1,-1):if wk[-1]>=tasks[i]:wk.pop()else:if p==0:return Falserep=wk.bisect_left(tasks[i]-strength)if rep==len(wk):return Falsep-=1wk.pop(rep)return Truel,r,ans=1,min(m,n),0while l<=r:mid=(l+r)//2if check(mid):ans=midl=mid+1else:r=mid-1return ans
5/2 838. 推多米诺
广搜BFS
使用l,r两个集合记录当前向左向右倾倒的位置
每一个向左的位置-1 如果位置上的骨牌状态为.则暂时标记可以倾倒
向右的一样
判断向左向右倾倒的位置是否有重复 如果有重复
这个位置将不会倾倒 去除这些位置
将可以倾倒的位置标记后 下一轮重新操作
def pushDominoes(dominoes):""":type dominoes: str:rtype: str"""dmn = list(dominoes)l,r = set(),set()for loc,c in enumerate(dmn):if c=="R":r.add(loc)elif c=="L":l.add(loc)n = len(dominoes)while l or r:tmpl,tmpr = set(),set()for loc in l:tmp = loc-1if tmp>=0 and dmn[tmp]==".":tmpl.add(tmp)for loc in r:tmp = loc+1if tmp<n and dmn[tmp]==".":tmpr.add(tmp)same = tmpl&tmprtmpl -= sametmpr -= same for loc in tmpl:dmn[loc]="L"for loc in tmpr:dmn[loc]="R"l = tmplr = tmprreturn "".join(dmn)
5/3 1007. 行相等的最少多米诺旋转
遍历记录数值在top出现的次数t[x] 在bottoms出现b[x]次
并统计每个位置数值出现次数nums[x]如果某个位置top,bottoms相同 则只在nums中统计一次
如果需要满足条件则必定存在某个数值x nums[x]=len(tops)
如果交换到top需要n-t[x]次 到下层需要n-b[x] 取小值
def minDominoRotations(tops, bottoms):""":type tops: List[int]:type bottoms: List[int]:rtype: int"""n=len(tops)nums=[0]*7t,b=[0]*7,[0]*7for i in range(n):t[tops[i]]+=1b[bottoms[i]]+=1nums[tops[i]]+=1if tops[i]!=bottoms[i]:nums[bottoms[i]]+=1for i in range(1,7):if nums[i]==n:return min(n-t[i],n-b[i])return -1
5/4 1128. 等价多米诺骨牌对的数量
依次遍历
def numEquivDominoPairs(dominoes):""":type dominoes: List[List[int]]:rtype: int"""m = {}ret = 0for a,b in dominoes:if a>b:a,b=b,atmp = m.get((a,b),0)m[(a,b)] = tmp+1for v in m.values():if v>=2:ret += (v-1)*v/2return ret