LeetCode笔记:Weekly Contest 288

比赛链接:https://leetcode.com/contest/weekly-contest-288

1. 题目一

给出题目一的试题链接如下:

1. 解题思路

这一题思路挺直接的,找到奇偶数出现的位置,然后分别重新排序一下即可。

就是实现上稍微麻烦一点。

2. 代码实现

给出python代码实现如下:

class Solution:
    def largestInteger(self, num: int) -> int:
        odd, odd_digits = [], []
        even, even_digits = [], []
        flag =1
        while num != 0:
            if num % 2 == 0:
                even.append((num % 10))
                even_digits.append(flag)
            else:
                odd.append(num % 10)
                odd_digits.append(flag)
            num = num // 10
            flag *= 10
        odd = sorted(odd)
        even = sorted(even)
        res = 0
        for x, d in zip(odd, odd_digits):
            res += x*d
        for x, d in zip(even, even_digits):
            res += x*d
        return res

提交代码评测得到:耗时61ms,占用内存13.7MB。

2. 题目二

给出题目二的试题链接如下:

1. 解题思路

这一题的思路同样也很直接,找到所有可以插入括号的位置然后遍历一下就行。

同样只是实现上多少有些繁琐。

2. 代码实现

给出python代码实现如下:

class Solution:
    def minimizeResult(self, expression: str) -> str:
        n = len(expression)
        idx = expression.find("+")
        _min = math.inf
        res = ""
        for i in range(idx):
            for j in range(idx+2, n+1):
                x = expression[:i]
                m = expression[i:j]
                y = expression[j:]
                expr = (x + "*(" + m + ")*" + y).strip("*")
                # print(expr, eval(expr))
                if eval(expr) < _min:
                    res = x + "(" + m + ")" + y
                    _min = eval(expr)
        return res

提交代码评测得到:耗时60ms,占用内存13.9MB。

3. 题目三

给出题目三的试题链接如下:

1. 解题思路

这一题同样没啥好说的,用二分法找到给定k的情况下能够把较小的数全部尽可能地平均放大的上限即可。

同样是实现比较麻烦,主要就是边界条件需要注意一下。

2. 代码实现

给出python代码实现如下:

class Solution:
    def maximumProduct(self, nums: List[int], k: int) -> int:
        MOD = 10**9 + 7
        
        nums = sorted(nums)
        cumsum = list(accumulate(nums))
        n = len(nums)
        i, j = nums[0], ceil((k + cumsum[-1]) / len(nums)) + 1
        while j-i > 1:
            m = (i+j) // 2
            idx = bisect.bisect_right(nums, m)
            delta = idx * m - cumsum[idx-1]
            if delta > k:
                j = m
            else:
                i = m
        
        idx = bisect.bisect_right(nums, i)
        j = k + cumsum[idx-1] - i * (idx)
        res = 1
        for _ in range(j):
            res = res * (i+1) % MOD
        for _ in range(idx-j):
            res = res * i % MOD
        for x in nums[idx:]:
            res = res * x % MOD
        return res

提交代码评测得到:耗时1311ms,占用内存26.1MB。

4. 题目四

给出题目四的试题链接如下:

1. 解题思路

这一题没能搞定,一直遇到超时问题,实在是放弃了。

这里仅仅抛砖引玉一下,给出我的超时code如下:

class Solution:
    def maximumBeauty(self, flowers: List[int], newFlowers: int, target: int, full: int, partial: int) -> int:
        flowers = sorted(flowers)
        cumsum = [0] + list(accumulate(flowers))
        n = len(flowers)
        m = bisect.bisect_left(flowers, target)
        if m == 0:
            return n * full
        
        def get_max_min(bound, k):
            if bound == 0:
                return 0
            i, j = flowers[0], target
            while j-i > 1:
                mid = (i+j) // 2
                idx = bisect.bisect_right(flowers[:bound], mid)
                delta = idx * mid - cumsum[idx]
                if delta > k:
                    j = mid
                else:
                    i = mid
            return i
        
        res = 0
        for i in range(m, -1, -1):
            delta = target * (m-i) - (cumsum[m] - cumsum[i])
            if delta > newFlowers:
                break
            remain = min(newFlowers - delta, newFlowers)
            res = max(res, (n-i) * full + get_max_min(i, remain) * partial)
        return res

后续也有尝试过认为0到m之间为一个单一高峰的数据分布,从而可以用二分法进行优化加速,不过实现之后发现这个单一峰值的假设是错误的,然后我就没招了,实在想不到什么方法可以优化后面那个遍历……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值