力扣 第471场周赛(A~D)

A:出现次数能被 K 整除的元素总和

签到题,给一个整数数组nums和一个数k,计算nums中出现次数能被k整除的数之和。

解法,做一个cnt,再遍历一遍就行了。

 1 class Solution:
 2     def sumDivisibleByK(self, nums: List[int], k: int) -> int:
 3         d=defaultdict()
 4         for x in nums:
 5             if x in d:
 6                 d[x]+=1
 7             else:
 8                 d[x]=1
 9         res=0
10         for x,v in d.items():
11             if v%k==0:
12                 res+=x*v
13         return res
View Code

B:最长的平衡子串 I

给定一个字符串s,求平衡子串的个数。平衡子串为串内出现的字母的出现次数都是相等的。

解法,因为s的长度最多为1000,那么可以直接枚举l和r,然后再做一个26的判定。时间复杂度为O(26*n^2)。

 1 class Solution:
 2     def longestBalanced(self, s: str) -> int:
 3         n=len(s)
 4         res=0
 5         for i in range(n):
 6             cnt=[0]*26
 7             for j in range(i,n):
 8                 cnt[ord(s[j])-ord('a')]+=1
 9                 minn,maxx=1010,0
10                 for k in range(26):
11                     if cnt[k]!=0:
12                         minn=min(minn,cnt[k])
13                         maxx=max(maxx,cnt[k])
14                 if minn==maxx and maxx!=0:
15                     res=max(res,j-i+1)
16         return res
View Code

C:最长的平衡子串 II

题意整体同B,但是s中只有'a','b','c'三种字符,且字符串长度到了1e5。

解法,那么如此就不能用平方级的解法了,因为字符种类变少了,那么合法的字符串只有可能是以下几种形式。全部由"a"、"b"、"c"、"a""b"、"a""c"、"b""c"、"a""b""c"组成。

单个字符的话,我们直接用最长连续就能计算。

现在我们考虑a,b,c都出现的情况,s的L~R的a,b,c三个字符出现次数相等,也就意味着suma[r]-suma[l-1]==sumb[r]-sumb[l-1]==sumc[r]-sumc[l-1],推导一下,能将后面的三种情况统一起来。

s表示sum,sa[r]-sb[r]==sa[l-1]-sb[l-1] && sa[r]-sc[r]==sa[l-1]-sc[l-1]。便于在遍历时维护,同时用上枚举右、维护左的方法。

 1 class Solution:
 2     def longestBalanced(self, s: str) -> int:
 3         res=0
 4         for key,group in groupby(s):
 5             res=max(res,len(list(group)))
 6         d_ABC=defaultdict()
 7         d_AB_C=defaultdict()
 8         d_AC_B=defaultdict()
 9         d_BC_A=defaultdict()
10         d_ABC[(0,0)]=-1
11         d_AB_C[(0,0)]=-1
12         d_AC_B[(0,0)]=-1
13         d_BC_A[(0,0)]=-1
14         A,B,C=0,0,0
15         for i,c in enumerate(s):
16             if c=='a':
17                 A+=1
18             elif c=='b':
19                 B+=1
20             else:
21                 C+=1
22             # abc都有
23             if (A-B,A-C) in d_ABC:
24                 res=max(res,i-d_ABC[(A-B,A-C)])
25             else:
26                 d_ABC[(A-B,A-C)]=i
27             # 只有ab
28             if (A-B,C) in d_AB_C:
29                 res=max(res,i-d_AB_C[(A-B,C)])
30             else:
31                 d_AB_C[(A-B,C)]=i
32 
33             if (A-C,B) in d_AC_B:
34                 res=max(res,i-d_AC_B[(A-C,B)])
35             else:
36                 d_AC_B[(A-C,B)]=i
37 
38             if (B-C,A) in d_BC_A:
39                 res=max(res,i-d_BC_A[(B-C,A)])
40             else:
41                 d_BC_A[(B-C,A)]=i
42         return res
View Code

D:完全平方数的祖先个数总和

给一棵数,节点上有值,当前节点和祖先相乘得到的数如果是完全平方数,则匹配,问有多少匹配的对数。

解法,两个数相乘是否是完全平方数,取决于他们去除冗余之后是否相等。去除冗余:x=360=2^3*3^2*5,去除冗余即为去除平方的项,x_kernel=2*5=10,那么如果y_kernel==10,那么他们就匹配。

所以,我们把nums去除冗余之后,再做一遍dfs的同时维护走过的节点的值出现次数即可。

 1 class Solution:
 2     def sumOfAncestors(self, n: int, edges: List[List[int]], nums: List[int]) -> int:
 3         def fun(x):
 4             res=1
 5             for i in range(2,isqrt(x)+1):
 6                 s=0
 7                 while x%i==0:
 8                     x//=i
 9                     s+=1
10                 if s%2==1:
11                     res*=i
12             if x>1:
13                 res*=x
14             return res
15         # 将偶数次幂去掉
16         for i in range(n):
17             nums[i]=fun(nums[i])
18         # print(nums)
19         g=[[] for i in range(n)]
20         for [u,v] in edges:
21             g[u].append(v)
22             g[v].append(u)
23         cnt=defaultdict()
24         res=0
25         def dfs(fa,u):
26             nonlocal res
27             if nums[u] in cnt:
28                 res+=cnt[nums[u]]
29                 cnt[nums[u]]+=1
30             else:
31                 cnt[nums[u]]=1
32             for v in g[u]:
33                 if v==fa:
34                     continue
35                 dfs(u,v)
36             cnt[nums[u]]-=1
37         dfs(-1,0)
38         return res
View Code

 

posted on 2025-10-12 18:00  greenofyu  阅读(16)  评论(0)    收藏  举报