考察的知识点:动态规划;
解答方法分析:
- 计算所有奶牛的总体重量
totalWeight
,并检查它是否能够被3整除。如果不能被3整除,那么无法将奶牛分成三组,直接返回false
。 - 确定每组的目标体重
targetWeight
,即totalWeight / 3
。 - 定义一个长度为3的数组
groupSums
,用于记录每组的体重和。初始时,所有组的和都为0。 - 调用回溯函数
backtrack(weights, 0, groupSums, targetWeight)
,尝试将奶牛分到三组中的某一组中。 - 在回溯函数中,首先查是否所有奶牛已经分完,即
index == weights.length
。如果是,则检查每组的体重和是否相等,如果相等则返回true
,否则返回false
。 - 如果奶牛还没有分完我们尝试将当前奶牛分到三组中的某一组中。遍历 0 到 2 的所有组,并检查将当前奶牛加入该组后,组的体重和是否小于等于目标体重
targetWeight
。如果是,则加入该组,并继续递归调用回溯函数,看能否成功将剩余的奶牛分到三组中。如果递归调用返回true
,则表示成功分组,返回true
。如果递归调用返回false
,则表示当前方式不可行,需要回溯,将当前奶牛从该组中移除,尝试其他组的分配方式。 - 如果所有组的分配方式都被尝试过后,仍然无法成功分组,则返回
false
。
所用编程语言:C++;
完整编程代码:↓
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param weights int整型vector * @return bool布尔型 */ bool backtrack(vector<int>& weights, int index, vector<int>& groupSums, int targetWeight) { if (index == weights.size()) { return groupSums[0] == targetWeight && groupSums[1] == targetWeight && groupSums[2] == targetWeight; } for (int i = 0; i < 3; ++i) { if (groupSums[i] + weights[index] <= targetWeight) { groupSums[i] += weights[index]; if (backtrack(weights, index + 1, groupSums, targetWeight)) { return true; } groupSums[i] -= weights[index]; } } return false; } bool canPartitionII(vector<int>& weights) { int n = weights.size(); int totalWeight = 0; for (int weight : weights) { totalWeight += weight; } if (totalWeight % 3 != 0) { return false; } int Weight = totalWeight / 3; vector<int> groupSums(3, 0); return backtrack(weights, 0, groupSums, Weight); } };