1. Element-to-Bucket Backtracking (K^N)
Intuition
Maintain an array bucket[k]. For element idx, try placing into bucket 0..k-1. If bucket[j] + nums[idx] <= target, recurse on idx + 1. When idx == n, check if all buckets equal target.
When to apply: Simple baseline concept.
Algorithm
- In
solve(idx): - - If
idx == n, check all buckets equaltarget. - - For each bucket
jfrom 0 tok - 1: - - If
bucket[j] + nums[idx] <= target: - -
bucket[j] += nums[idx]. - - Recurse
solve(idx + 1). - -
bucket[j] -= nums[idx].
#include <iostream>#include <vector>#include <numeric>#include <algorithm> using namespace std; class Solution { bool solve(int idx, int k, int target, const vector<int>& nums, vector<int>& buckets) { if (idx == nums.size()) { for (int v : buckets) if (v != target) return false; return true; } for (int j = 0; j < k; j++) { if (buckets[j] + nums[idx] <= target) { buckets[j] += nums[idx]; if (solve(idx + 1, k, target, nums, buckets)) return true; buckets[j] -= nums[idx]; } } return false; } public: bool canPartitionKSubsets(vector<int>& nums, int k) { int sum = accumulate(nums.begin(), nums.end(), 0); if (sum % k != 0 || nums.size() < k) return false; int target = sum / k; vector<int> buckets(k, 0); return solve(0, k, target, nums, buckets); }}; int main() { Solution sol; vector<int> nums = {4, 3, 2, 3, 5, 2, 1}; cout << (sol.canPartitionKSubsets(nums, 4) ? "true" : "false") << endl; return 0;}Time & Space Complexity
- Time complexity:
O(K^N)— Branches K ways for each of the N numbers. - Space complexity:
O(N + K)— Recursion stack depth N.