Leetcode 3489. Zero Array Transformation IV

1. 解题思路

这一题我的思路就是一个二分法,即给定一个值 k k k,考察前 k k k个query能否将原始数组全变为0。显然,如果原始数组能完全变为0,则必然存在一个临界值 k ′ k' k,使得对任意 k ≥ k ′ k \geq k' kk,数组都能变为 0 0 0,反之对任意 k < k ′ k < k' k<k,数组都不能变为 0 0 0。此时,通过二分法,我们就能找到 k k k的临界值 k ′ k' k

此时,问题就变成了给出一个值 k k k,如何判断每一个元素是否可以变为 0 0 0,考虑到数组最多也就10个元素,因此,我们可以依次考察每一个位置上的可变动范围,然后分别考察每一个元素是否可以变为 0 0 0即可。

即,我们最终的问题也就变成了,给定一个数组,能否从中选取若干个元素,使之加和恰好为一个确定的目标值 x x x。这就是一个典型的动态规划的问题了。

综上,命题完全求解。

2. 代码实现

给出python代码实现如下:

class Solution:
    def minZeroArray(self, nums: List[int], queries: List[List[int]]) -> int:
        if all(x == 0 for x in nums):
            return 0
        
        def is_possible(k):
            candidates = [[] for _ in nums]
            for l, r, v in queries[:k]:
                for i in range(l, r+1):
                    candidates[i].append(v)
            candidates = [sorted(x, reverse=True) for x in candidates]
            
            @lru_cache(None)
            def _is_possible(i, idx, tgt):
                if tgt == 0:
                    return True
                if i >= len(candidates[idx]):
                    return False
                if candidates[idx][i] == tgt:
                    return True
                elif candidates[idx][i] > tgt:
                    return _is_possible(i+1, idx, tgt)
                else:
                    return _is_possible(i+1, idx, tgt-candidates[idx][i]) or _is_possible(i+1, idx, tgt)
                
            return all(_is_possible(0, idx, num) for idx, num in enumerate(nums))
        
        l, r = 0, len(queries)
        if not is_possible(r):
            return -1
        while r-l>1:
            m = (l+r)//2
            if is_possible(m):
                r = m
            else:
                l = m
        return r

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值