链接: 6253. 回环句
按题意模拟即可。
class Solution:
def isCircularSentence(self, sentence: str) -> bool:
s = sentence.split()
if s[-1][-1] != s[0][0]:
return False
for i in range(len(s)-1):
if s[i][-1] != s[i+1][0]:
return False
return True
链接: 6254. 划分技能点相等的团队
class Solution:
def dividePlayers(self, skill: List[int]) -> int:
skill.sort()
n = len(skill)
l,r = 0,n-1
s = skill[l] + skill[r]
ans = 0
while l<r:
if skill[l] + skill[r] != s:
return -1
ans += skill[l]* skill[r]
l += 1
r -= 1
return ans
class Solution:
def minScore(self, n: int, roads: List[List[int]]) -> int:
g = [[] for _ in range(n)]
for u,v,w in roads:
u -= 1
v -= 1
g[u].append((v,w))
g[v].append((u,w))
vis = [0]*n
ans = inf
def dfs(u):
vis[u] = 1
nonlocal ans
for v,w in g[u]:
ans = min(ans,w)
if not vis[v]:
dfs(v)
dfs(0)
return ans
比赛时没做出来,赛后默写灵神的题解。
实际上就是两个模板,但不先找出规律,做出推论,也是想不到的。
class Solution:
def magnificentSets(self, n: int, edges: List[List[int]]) -> int:
""" 推论: 如果是树/森林,有答案
如果有奇环,无答案。
没有奇环=二分图,因此
用dfs判断是否是二分图
用bfs枚举一个连通块中的每个点作为起点,给其它块染色最多染几组出来,即求连通块最大深度
"""
g = [[] for _ in range(n)]
for u,v in edges:
g[u-1].append(v-1)
g[v-1].append(u-1)
colors = [0]*n
def dfs(u,c): # 判断是否是二分图
colors[u] = c
nodes.append(u)
for v in g[u]:
if colors[v] == c or not colors[v] and not dfs(v,3-c): # 注意这个染色是标记1/2
return False
return True
vis = [-1]*n
def bfs(start): # 以start为起点,计算这个连通分量的深度,用时间戳来优化vis,类似匈牙利的vis,这里由于每个点只会作为起点一次,所以可以用start
q = deque([start])
vis[start] = start
depth = 0
while q:
depth += 1
for _ in range(len(q)):
u = q.popleft()
for v in g[u]:
if vis[v] != start:
vis[v] = start
q.append(v)
return depth
ans = 0
for i,c in enumerate(colors): # 染色1/2是分组,0是未访问
if not c:
nodes = [] # 当前连通块的所有点
if not dfs(i,1): # 如果不是二分图,无答案
return -1
ans += max(bfs(x) for x in nodes) # 枚举一个连通块中每个起点,找最大深度
return ans