力扣周赛191场

周赛小结

P1, P2 送分题。P3,只要理解图的性质等同于送分题。P4注意到数据大小后,基本也是简单题。

P1. 数组中两元素的最大乘积

给你一个整数数组 nums,请你选择数组的两个不同下标 i 和 j,使 (nums[i]-1)*(nums[j]-1) 取得最大值。

请你计算并返回该式的最大值。

class Solution:
    def maxProduct(self, A: List[int]) -> int:
        n,ret = len(A), 0
        for i in range(n):
            for j in range(n):
                if i!=j: 
                    ret = max(ret, (abs(A[i])-1)*(abs(A[j])-1))
        return ret

P2 切割后面积最大的蛋糕

矩形蛋糕的高度为 h 且宽度为 w,给你两个整数数组 horizontalCuts 和 verticalCuts,其中 horizontalCuts[i] 是从矩形蛋糕顶部到第 i 个水平切口的距离,类似地, verticalCuts[j] 是从矩形蛋糕的左侧到第 j 个竖直切口的距离。

请你按数组 horizontalCuts 和 verticalCuts 中提供的水平和竖直位置切割后,请你找出 面积最大 的那份蛋糕,并返回其 面积 。由于答案可能是一个很大的数字,因此需要将结果对 10^9 + 7 取余后返回。

class Solution:
    def maxArea(self, h: int, w: int, A: List[int], B: List[int]) -> int:
        A, B = [0]+sorted(A)+[h],[0]+sorted(B)+[w]
        maxA, maxB, mod = 0,0,10**9 + 7
        for i,x in enumerate(A):
            if i+1 < len(A): maxA = max(maxA, A[i+1]-x)
        for i,x in enumerate(B):
            if i+1 < len(B): maxB = max(maxB, B[i+1]-x)
        return maxA * maxB % mod
            

P3. 重新规划路线

n 座城市,从 0 到 n-1 编号,其间共有 n-1 条路线。因此,要想在两座不同城市之间旅行只有唯一一条路线可供选择(路线网形成一颗树)。去年,交通运输部决定重新规划路线,以改变交通拥堵的状况。

路线用 connections 表示,其中 connections[i] = [a, b] 表示从城市 a 到 b 的一条有向路线。

今年,城市 0 将会举办一场大型比赛,很多游客都想前往城市 0 。

请你帮助重新规划路线方向,使每个城市都可以访问城市 0 。返回需要变更方向的最小路线数。

题目数据 保证 每个城市在重新规划路线方向后都能到达城市 0 。

解:
因为题目保证各点相连无环,且边数比点数小1。 而且,不破坏原本结构,只改变方向。 所以只要贪心的去计算,这些是否能到达0点。
对于有向边(s,t), 有一些简单的性质:

  1. 如果t在结果集, 那么我们就把s放到结果集就行了
  2. 如果s在结果集, 那么我们一定能保证t不在结果集, 那么我们就改变有向边的方向。
  3. 如果s,t都不在结果集,那么我们就放一放,稍后处理。
class Solution:
    def minReorder(self, n: int, connections: List[List[int]]) -> int:
        dst,ret = set([0]), 0
        while connections:
            s,t = connections[0]
            del connections[0]
            if s in dst: 
                ret += 1
                dst.add(t)
            elif t in dst:
                dst.add(s)
            else:
                connections.append([s,t])
        return ret
            

P4 两个盒子中球的颜色数相同的概率

给你一个整数数组 nums,请你选择数组的两个不同下标 i 和 j,使 (nums[i]-1)*(nums[j]-1) 取得最大值。

请你计算并返回该式的最大值。
解: 数据量太小了, 可以直接暴力计算。

from functools import lru_cache
class Solution:
    def getProbability(self, balls: List[int]) -> float:
        cols = len(balls)
        @lru_cache(None)
        def frac(x):
            if x == 1: return 1
            return x * frac(x-1)
        def per(A):
            total = frac(sum(A))
            for x in A: total //= frac(x)
            return total
        total = per(balls)
        cnt, n = 0, sum(balls) // 2
        def solve(balls, b1, b2,B1, B2,cnt1, cnt2):
            nonlocal cnt
            if cnt1 > n or cnt2 > n: 
                return 
            if not balls:
                if b1 == b2:
                    cnt += per(B1)*per(B2)
                return 
            for i in range(balls[0]+1):
                if i == 0:
                    solve(balls[1:], b1, b2+1,B1, B2+[balls[0]], cnt1, cnt2+balls[0])
                elif i == balls[0]:
                    solve(balls[1:], b1+1, b2,B1+[balls[0]],B2, cnt1 + i, cnt2)
                else:
                    solve(balls[1:], b1+1, b2+1,B1+[i], B2+[balls[0]-i], cnt1 + i, cnt2+balls[0]-i)
        solve(balls, 0,0,[],[], 0, 0)
        return cnt / total
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值