[Leetcode Weekly Contest]191
链接:LeetCode
[Leetcode]5424. 数组中两元素的最大乘积
给你一个整数数组 nums,请你选择数组的两个不同下标 i 和 j,使 (nums[i]-1)*(nums[j]-1) 取得最大值。
请你计算并返回该式的最大值。
由于均为正整数,故只要找出最大地两个数即可。
class Solution:
def maxProduct(self, nums: List[int]) -> int:
nums.sort()
res = (nums[-1]-1) * (nums[-2]-1)
return res
[Leetcode]5425. 切割后面积最大的蛋糕
矩形蛋糕的高度为 h 且宽度为 w,给你两个整数数组 horizontalCuts 和 verticalCuts,其中 \(horizontalCuts[i]\)是从矩形蛋糕顶部到第 i 个水平切口的距离,类似地, \(verticalCuts[j]\)是从矩形蛋糕的左侧到第 j 个竖直切口的距离。
请你按数组 horizontalCuts 和 verticalCuts 中提供的水平和竖直位置切割后,请你找出 面积最大 的那份蛋糕,并返回其 面积 。由于答案可能是一个很大的数字,因此需要将结果对 10^9 + 7 取余后返回。
如果知道切完后蛋糕的最大高度及宽度,那么就可以求得最大面积,排序求乘积即可。
class Solution:
def maxArea(self, h: int, w: int, horizontalCuts: List[int], verticalCuts: List[int]) -> int:
horizontalCuts = [0] + horizontalCuts + [h]
verticalCuts = [0] + verticalCuts + [w]
horizontalCuts.sort()
verticalCuts.sort()
res = self.getMaxGap(horizontalCuts) * self.getMaxGap(verticalCuts)
return res%(10**9 + 7)
def getMaxGap(self,nums):
res = 0
for i in range(1,len(nums)):
res = max(res,nums[i]-nums[i-1])
return res
[Leetcode]5426. 重新规划路线
n 座城市,从 0 到 n-1 编号,其间共有 n-1 条路线。因此,要想在两座不同城市之间旅行只有唯一一条路线可供选择(路线网形成一颗树)。去年,交通运输部决定重新规划路线,以改变交通拥堵的状况。
路线用 connections 表示,其中\(connections[i] = [a, b]\)表示从城市 a 到 b 的一条有向路线。
今年,城市 0 将会举办一场大型比赛,很多游客都想前往城市 0 。
请你帮助重新规划路线方向,使每个城市都可以访问城市 0 。返回需要变更方向的最小路线数。
题目数据 保证 每个城市在重新规划路线方向后都能到达城市 0 。
记录入度与出度,通过BFS求解。
import collections
class Solution:
def minReorder(self, n: int, connections: List[List[int]]) -> int:
graph = collections.defaultdict(list)
queue = deque()
queue.append(0)
res = 0
visited = set([0])
for u, v in connections:
graph[u].append((v, 1))
graph[v].append((u, 0))
while queue:
p = queue.pop()
for node, flag in graph[p]:
if node in visited: continue # 如果访问过就不管了
res += flag
queue.appendleft(node)
visited.add(node)
return res
[Leetcode]5427. 两个盒子中球的颜色数相同的概率
桌面上有 2n 个颜色不完全相同的球,球上的颜色共有 k 种。给你一个大小为 k 的整数数组 balls ,其中 balls[i] 是颜色为 i 的球的数量。
所有的球都已经 随机打乱顺序 ,前 n 个球放入第一个盒子,后 n 个球放入另一个盒子(请认真阅读示例 2 的解释部分)。
注意:这两个盒子是不同的。例如,两个球颜色分别为 a 和 b,盒子分别为 \([]\) 和 (),那么 \([a] (b)\)和\([b] (a)\)这两种分配方式是不同的(请认真阅读示例 1 的解释部分)。
请计算「两个盒子中球的颜色数相同」的情况的概率。
DFS 遍历每一种颜色,需要在每一层保存当前的组合数(即有多少种可能的方式到达当前的状态),在遍历到该颜色时,假设该颜色有 nc 个球,可以取出的球的数量是 \([0, nc]\)。在这一层做循环,依次拿出 0 到 nc 个球,同时计算这种选择的组合数,和上一层组合数相乘,进入下一层。
class Solution:
def getProbability(self, balls) -> float:
# c1 是第一个箱子中的颜色数量,c2 是第二个箱子中的颜色数量
c1, c2 = 0, 0
# 所有的满足条件的取球的方式数量
self.res = 0
# 所有的取球的方式数量
self.total = 0
self.balls = balls
self.target_count = sum(balls) // 2
# 题目说明了每种颜色的球数量最大为 6,因此计算 0~6 的阶乘,后面直接查
self.fact = [1] * 7
for i in range(1, 7):
self.fact[i] = self.fact[i-1]*i
self.dfs(1, 0, 0, c1, c2)
return self.res / self.total
# choices: 到达这一层的状态时,所有可能的方式数量
# counts: 已经取出来的球的数量
# ball_idx:这一层要从哪种颜色里面取
# c1: 第一个箱子中的颜色数量
# c2: 第二个箱子中的颜色数量
def dfs(self, choices, counts, ball_idx, c1, c2):
# 如果取的球太多了,直接返回
if counts > self.target_count:
return
# 如果取完了所有的颜色,判断两个箱子中的颜色数量是否相同
if ball_idx == len(self.balls):
if counts != self.target_count:
return
self.total += choices
if c1 == c2:
self.res += choices
return
# 这种颜色一共有多少球
this_ball_num = self.balls[ball_idx]
# 取出 i 个球放在第一个箱子,其余的放入第二个箱子
for i in range(this_ball_num+1):
c11 = c1+1 if i > 0 else c1
c22 = c2+1 if i < this_ball_num else c2
this_choice = self.fact[this_ball_num] / self.fact[i] / self.fact[this_ball_num-i]
self.dfs(choices * this_choice, counts+i, ball_idx+1, c11, c22)
参考:
leetcode