/**
<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)
leetcode回溯-698
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.