给定一个整数数组 nums
和一个正整数 k
,找出是否有可能把这个数组分成 k
个非空子集,其总和都相等。
示例 1:
输入: nums = [4, 3, 2, 3, 5, 2, 1], k = 4 输出: True 说明: 有可能将其分成 4 个子集(5),(1,4),(2,3),(2,3)等于总和。
|
示例 2:
输入: nums = [1,2,3,4], k = 3 输出: false
|
提示:
1 <= k <= len(nums) <= 16
0 < nums[i] < 10000
- 每个元素的频率在
[1,4]
范围内
C++
class Solution { public: bool canPartitionKSubsets(vector<int>& nums, int k) { int sum =0; for(int t: nums) sum += t; if(sum % k) return false; int s = sum / k; vector<int> buckets(k, s); sort(nums.rbegin(), nums.rend()); return backtracking(nums, buckets, k, 0); }
bool backtracking(vector<int>& nums, vector<int> buckets, int k, int idx) { if(idx >= nums.size()) return true;
for(int i = 0; i < k; i ++){ if(nums[idx] > buckets[i]) continue; if(i > 0 && buckets[i] == buckets[i -1]) continue; buckets[i] -= nums[idx]; if(backtracking(nums, buckets, k, idx + 1)) return true; buckets[i] += nums[idx]; } return false; } };
|
你将得到一个整数数组 matchsticks
,其中 matchsticks[i]
是第 i
个火柴棒的长度。你要用 所有的火柴棍 拼成一个正方形。你 不能折断 任何一根火柴棒,但你可以把它们连在一起,而且每根火柴棒必须 使用一次 。
如果你能使这个正方形,则返回 true
,否则返回 false
。
示例 1:
输入: matchsticks = [1,1,2,2,2] 输出: true 解释: 能拼成一个边长为2的正方形,每边两根火柴。
|
示例 2:
输入: matchsticks = [3,3,3,3,4] 输出: false 解释: 不能用所有火柴拼成一个正方形。
|
提示:
1 <= matchsticks.length <= 15
1 <= matchsticks[i] <= 108
C++
class Solution { public: bool makesquare(vector<int>& matchsticks) { int sum = 0; for(int e : matchsticks) sum += e; if(sum % 4) return false; int target = sum/4; sort(matchsticks.rbegin(), matchsticks.rend()); vector<int> buckets(4, target); return backtracking(matchsticks, buckets, 0); }
bool backtracking(vector<int>& matchsticks, vector<int> buckets, int idx){ if(idx >= matchsticks.size()) return true;
for(int i = 0; i < 4; i++){ if(buckets[i] < matchsticks[idx]) continue; if(i > 0 && buckets[i] == buckets[i - 1]) continue;
buckets[i] -= matchsticks[idx]; if(backtracking(matchsticks, buckets, idx + 1)) return true; buckets[i] += matchsticks[idx]; } return false; } };
|