执行操作使所有数组元素变为零

0 投票
1 回答
176 浏览
提问于 2025-04-14 18:36

我尝试了解决这个LeetCode的问题,结果我的方案通过了1017个测试用例中的1026个。剩下的那些失败的测试用例是因为超时,而不是我的方案错误。所以我在想,有没有人能给我一些优化的方法。我知道问题出在我每次都要在子列表中找到最小值。我觉得可以用一些前缀和的逻辑来优化,但我不太确定该怎么把它引入我的方法中。

这是题目:

给你一个从0开始索引的整数数组nums和一个正整数k。

你可以对数组进行以下操作任意次数:

选择数组中任意大小为k的子数组,并将所有元素减1。如果你能让数组中的所有元素都变为0,就返回true,否则返回false。

子数组是数组中连续的非空部分。

例子1:

输入:nums = [2,2,3,1,1,0], k = 3 输出:true

解释:我们可以进行以下操作:

  • 选择子数组[2,2,3]。结果数组变为nums = [1,1,2,1,1,0]。
  • 选择子数组[2,1,1]。结果数组变为nums = [1,1,1,0,0,0]。
  • 选择子数组[1,1,1]。结果数组变为nums = [0,0,0,0,0,0]。

例子2:

输入:nums = [1,3,1,1], k = 2 输出:false

解释:无法让所有数组元素都变为0。

这是我的代码:

def checkArray(self, nums: List[int], k: int) -> bool:
        i, j = 0, k        
        while i + k <= len(nums):            
            sublist = nums[i:j]  # Make a copy of the sublist            
            smallest = min(sublist)
            for x in range(len(sublist)):                
                sublist[x] -= smallest  # Modify the values in the sublist
                if x > 0 and sublist[x] < sublist[x-1]:
                    return False
            nums[i:j] = sublist  # Assign the modified sublist back to the original list            
            i += 1
            j += 1
        return sum(nums) == 0

这是我的思路,方便大家理解我的方法:

我使用了滑动窗口。在每个窗口内,我们做了两件事:模拟应用操作以将元素减少到0,同时检查窗口是否有效。窗口有效的条件是,当前遍历的元素左边没有元素在模拟完成后仍然大于它。这是有道理的,因为如果左边的元素比它大,说明左边的元素在大小为k的窗口内无法减到0。这里的模拟是指,我们不需要不断地从窗口内的所有元素中减去1,直到最小值变为0,而是找到窗口内的最小元素,然后从窗口内的所有元素中减去这个最小值。这样做的结果是一样的,但效率更高。

1 个回答

2

我们可以采用一种贪心的方法:每当我们在向前遍历时遇到一个非零的元素,就把从这个元素开始的大小为 k 的整个范围内的值都减去这个元素的值。我们不需要在这个范围内寻找最小值;如果范围内有任何值小于左端点的值,那么就不可能把所有元素都变成0。为了快速进行范围更新,我们可以使用一个差分数组。

示例实现:

class Solution:
    def checkArray(self, nums: List[int], k: int) -> bool:
        diff = [0] * (len(nums) + 1)
        for i, v in enumerate(nums):
            if i: diff[i] += diff[i - 1]
            v += diff[i]
            if v < 0: return False
            if v:
                if i + k > len(nums): return False
                diff[i] -= v
                diff[i + k] += v
        return True

撰写回答