LeetCode 每日一题 2025/4/21-2025/4/27
记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
- 4/21 2145. 统计隐藏数组数目
- 4/22 2338. 统计理想数组的数目
- 4/23 1399. 统计最大组的数目
- 4/24 2799. 统计完全子数组的数目
- 4/25 2845. 统计趣味子数组的数目
- 4/26 2444. 统计定界子数组的数目
- 4/27 3392. 统计符合条件长度为 3 的子数组数目
4/21 2145. 统计隐藏数组数目
依次遍历找到最小值vmin 最大值vmax
假设lower是vmin 那么此时最大值为lower+(vmax-vmin)
个数为upper-(lower+(vmax-vmin))+1
def numberOfArrays(differences, lower, upper):""":type differences: List[int]:type lower: int:type upper: int:rtype: int"""vmax,vmin=0,0cur=0for v in differences:cur+=vvmax=max(vmax,cur)vmin=min(vmin,cur)return max(0,upper-(lower+(vmax-vmin))+1)
4/22 2338. 统计理想数组的数目
dp[i][j]表示以i结尾 有j个不同数字组成的方案 dp[i][1]=1
考虑i有n个质因数 分为j份 隔板法n-1个位置插入j-1个隔板 C(j-1),(n-1)
c[i][j]=c[i-1][j]+c[i-1][j-1]
def idealArrays(n, maxValue):""":type n: int:type maxValue: int:rtype: int"""MOD=10**9+7c=[[0]*16 for _ in range(n)]for i in range(n):for j in range(min(i+1,16)):c[i][j]=1 if j==0 else (c[i-1][j]+c[i-1][j-1])% MODdp=[[0]*16 for _ in range(maxValue+1)]for i in range(1,maxValue+1):dp[i][1]=1for j in range(1,15):for i in range(1,maxValue+1):k=2while k*i<=maxValue:dp[k*i][j+1]=(dp[k*i][j+1]+dp[i][j])%MODk+=1ans=0for i in range(1,maxValue+1):for j in range(1,16):ans = (ans+dp[i][j]*c[-1][j-1])%MODreturn ans
4/23 1399. 统计最大组的数目
依次遍历 map记录数位和
def countLargestGroup(n):""":type n: int:rtype: int"""m={}for i in range(1,n+1):s = sum([int(x) for x in str(i)])m[s]=m.get(s,0)+1maxv = max(m.values())ans=0for v in m.values():if v==maxv:ans+=1return ans
4/24 2799. 统计完全子数组的数目
统计不同整数个数
子数组中所有整数至少出现一次
滑动窗口 固定左边界l 找到满足的位置r 就会有n-r+1个完全子数组
def countCompleteSubarrays(nums):""":type nums: List[int]:rtype: int"""n=len(nums)num=len(set(nums))m={}ans=0r=0for l in range(n-num+1):if l>0:v=nums[l-1]m[v]-=1if m[v]==0:m.pop(v)while r<n and len(m)<num:v=nums[r]m[v]=m.get(v,0)+1r+=1if len(m)==num:ans+=n-r+1return ans
4/25 2845. 统计趣味子数组的数目
遍历判断每个数字是否满足%modulo==k 满足为1 不满足为0
将数组转换为0,1数组
将这个数组求前缀和得到cur, cur[x]即为[0~x]间的cnt值
使用哈希表m[v]记录当前位置之前前缀和为v的次数
def countInterestingSubarrays(nums, modulo, k):""":type nums: List[int]:type modulo: int:type k: int:rtype: int"""n=len(nums)cur=[0]*nnum = 0for i,v in enumerate(nums):if v%modulo==k:num+=1cur[i]=numm={}m[0]=1ans=0for v in cur:x=(v-k+modulo)%moduloans+=m.get(x,0)m[v%modulo]=m.get(v%modulo,0)+1return ans
4/26 2444. 统计定界子数组的数目
从头遍历
以当前位置i为右端点
记录左侧出现过的最大值、最小值位置maxi mini
以及最近的不在范围内数值位置vi
左端点范围在vi+1,min(mini,maxi)之间
def countSubarrays(nums, minK, maxK):""":type nums: List[int]:type minK: int:type maxK: int:rtype: int"""ans=0mini=maxi=vi=-1for i,x in enumerate(nums):if x==minK:mini=iif x==maxK:maxi=iif x<minK or x>maxK:vi=ians+=max(0,min(mini,maxi)-vi)return ans
4/27 3392. 统计符合条件长度为 3 的子数组数目
从头遍历
def countSubarrays(nums):""":type nums: List[int]:rtype: int"""ans = 0for i in range(len(nums)-2):if (nums[i]+nums[i+2])*2==nums[i+1]:ans+=1return ans