You are given an integer array cookies
, where cookies[i]
denotes the number of cookies in the ith
bag. You are also given an integer k
that denotes the number of children to distribute all the bags of cookies to. All the cookies in the same bag must go to the same child and cannot be split up.
The unfairness of a distribution is defined as the maximum total cookies obtained by a single child in the distribution.
Return the minimum unfairness of all distributions.
Example 1:
Input: cookies = [8,15,10,20,8], k = 2 Output: 31 Explanation: One optimal distribution is [8,15,8] and [10,20] - The 1st child receives [8,15,8] which has a total of 8 + 15 + 8 = 31 cookies. - The 2nd child receives [10,20] which has a total of 10 + 20 = 30 cookies. The unfairness of the distribution is max(31,30) = 31. It can be shown that there is no distribution with an unfairness less than 31.
Example 2:
Input: cookies = [6,1,3,2,2,4,1,2], k = 3 Output: 7 Explanation: One optimal distribution is [6,1], [3,2,2], and [4,1,2] - The 1st child receives [6,1] which has a total of 6 + 1 = 7 cookies. - The 2nd child receives [3,2,2] which has a total of 3 + 2 + 2 = 7 cookies. - The 3rd child receives [4,1,2] which has a total of 4 + 1 + 2 = 7 cookies. The unfairness of the distribution is max(7,7,7) = 7. It can be shown that there is no distribution with an unfairness less than 7.
Constraints:
2 <= cookies.length <= 8
1 <= cookies[i] <= 105
2 <= k <= cookies.length
This problem asks for the minimum unfairness in distributing cookies among children, where unfairness is defined as the maximum number of cookies any single child receives. The solution uses a backtracking approach with pruning to efficiently explore the search space.
Approach:
Sorting: The cookies
array is sorted in descending order. This is a crucial optimization. By starting with the largest cookies, the algorithm is more likely to find a good distribution early, and pruning will be more effective.
Backtracking: The core of the solution is a recursive dfs
(depth-first search) function. It iterates through each cookie bag. For each bag, it explores assigning that bag to each child.
State: The cnt
array tracks the number of cookies each child currently possesses.
Pruning: This is where the efficiency comes in. Several checks prevent unnecessary exploration:
cnt[j] + cookies[i] >= ans
: If adding the current cookie bag to a child's existing cookies would exceed the current minimum unfairness (ans
), there's no need to continue exploring this branch. The algorithm has already found a better solution.(j and cnt[j] == cnt[j - 1])
: This condition prevents exploring branches where a child would receive the same amount of cookies as a previous child, assuming no better solution will come from such a configuration. It acts as additional pruning for identical situationsBase Case: When all cookie bags are assigned (i >= len(cookies)
), the maximum number of cookies among all children is calculated, and ans
(the minimum unfairness) is updated if a better distribution is found.
Backtracking: After exploring a branch, the algorithm backtracks by removing the cookie bag from the child's count, allowing exploration of other assignments.
Time Complexity Analysis:
The time complexity is difficult to express precisely. In the worst case, the algorithm might explore all possible distributions of cookies. If there are n
cookies and k
children, this could lead to kn possible assignments. However, the pruning significantly reduces the actual number of explored branches. The actual runtime depends heavily on the input data and the effectiveness of the pruning. In the best case (with effective pruning), the time complexity could be much lower. We can describe it as O(kn) in the worst case, but in practice, it is substantially better due to pruning.
Space Complexity Analysis:
The space complexity is dominated by the recursion stack, which has a depth proportional to the number of cookies (n
). Therefore, the space complexity is O(n).
Example (Python):
Let's trace a simplified example with cookies = [8, 15, 10]
and k = 2
.
dfs(0)
is called.cnt
becomes [8, 0]
.dfs(1)
is called. It tries assigning 15.cnt
is [23, 0]
. The pruning condition cnt[j] + cookies[i] >= ans
may or may not activate depending on the current ans
.ans
is updated accordingly through backtracking.The provided code in Python, Java, C++, Go, and TypeScript all implement this backtracking algorithm with pruning. They differ slightly in syntax and specific implementation details but maintain the same fundamental approach.