416. 分割等和子集

Zesari 发布于 2025-01-24 96 次阅读


背景

第一眼看到 416. 分割等和子集 - 力扣(LeetCode) 想用回溯,虽一想这里回溯时间复杂度是 O(2n),但是手痒痒还是写了下。果不其然,在第37个测试用例超时了

闲来无事想了想,这里只写了当发现可行时返回true的逻辑,如果返回false呢?首先考虑下false是从哪里返回的,实际上只能是当 `tempSum > sum` 的时候。而数组又是顺序排序的,后面的元素更大加到 tempSum 上只会触发 `tempSum > sum`,那直接返回吧,还要后面干啥?

于是我加了一个else:

for (let i = startIndex; i < nums.length; i ++) {
    tempSum += nums[i]
    if (backTracing(nums, tempSum, i + 1)) {
        return true
    } else {
        return false
    }
    tempSum -= nums[i]
}

一看到了第73个样例,还挺高兴,但是一看报错的输入发现自己想的太简单了... ...

哦,1 + 1 + 2 > 3,所以就终止了... ... 1 + 2 压根都没出现过还。不加之前还只是超时,加了之后产生了错误

我还想能不能把 [2, 2, 1, 1] 按照 [1, 2, 1, 2]这样排序,兴许有效。但想了想还是有用例肯定无法通过:如 [1,5,11,5],因为当 1 + 5 + 11 > 11时,else 就返回false了

看来这个题不能用回溯做 ... ...

当成0-1背包问题做,数组中每个数视为一个物品,价值和体积就是当前数的大小

把问题视为:当容量为所有物品容量总和的一半时,判断当前总价值是否与所有物品价值总和的一半相等

Hello, It's me.
最后更新于 2025-01-24