leetcode回溯-698
/**
<p>给定一个整数数组 <code>nums</code> 和一个正整数 <code>k</code>,找出是否有可能把这个数组分成 <code>k</code> 个非空子集,其总和都相等。</p>
<p> </p>
<p><strong>示例 1:</strong></p>
<pre>
<strong>输入:</strong> nums = [4, 3, 2, 3, 5, 2, 1], k = 4
<strong>输出:</strong> True
<strong>说明:</strong> 有可能将其分成 4 个子集(5),(1,4),(2,3),(2,3)等于总和。</pre>
<p><strong>示例 2:</strong></p>
<pre>
<strong>输入:</strong> nums = [1,2,3,4], k = 3
<strong>输出:</strong> false</pre>
<p> </p>
<p><strong>提示:</strong></p>
<ul>
<li><code>1 <= k <= len(nums) <= 16</code></li>
<li><code>0 < nums[i] < 10000</code></li>
<li>每个元素的频率在 <code>[1,4]</code> 范围内</li>
</ul>
<div><div>Related Topics</div><div><li>位运算</li><li>记忆化搜索</li><li>数组</li><li>动态规划</li><li>回溯</li><li>状态压缩</li></div></div><br><div><li>👍 599</li><li>👎 0</li></div>
*/
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public static boolean canPartitionKSubsets(int[] nums, int k) {
//平分的桶子大于数组个数
if (k > nums.length) {
return false;
}
//所有数字和无法平分
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
}
if (sum % k != 0) {
return false;
}
int[] bucket = new int[k];
int target = sum / k;
return backtrack(nums, 0, bucket, target);
}
//以数字的角度
static boolean backtrack(int[] nums, int index, int[] bucket, int target) {
if (index == nums.length) {
for (int i = 0; i < bucket.length; i++) {
if (bucket[i] != target) {
return false;
}
return true;
}
}
for (int i = 0; i < bucket.length; i++) {
//剪枝 桶子满了
if (bucket[i] + nums[index] > target) {
continue;
}
bucket[i] += nums[index];
if (backtrack(nums, index + 1, bucket, target)) {
return true;
}
bucket[i] -= nums[index];
}
return false;
}
}
//leetcode submit region end(Prohibit modification and deletion)
不恋尘世浮华,不写红尘纷扰
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理