leetcode回溯-698

/** <p>給定一個整數數組&nbsp;&nbsp;<code>nums</code> 和一個正整數 <code>k</code>,找出是否有可能把這個數組分成 <code>k</code> 個非空子集,其總和都相等。</p> <p>&nbsp;</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>&nbsp;</p> <p><strong>提示:</strong></p> <ul> <li><code>1 &lt;= k &lt;= len(nums) &lt;= 16</code></li> <li><code>0 &lt; nums[i] &lt; 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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章