Given two integers n and k, where n represents the total number of candies and k represents the number of people, distribute the candies in rounds.
- In the first round, the first person receives 1 candy, the second person receives 2 candies, and so on until the kth person receives k candies.
- In the next round, the first person receives k + 1 candies, the second person receives k + 2 candies, and this pattern continues.
If the remaining candies are fewer than the required candies for a person, that person receives all the remaining candies.
Return an array arr of size k, where arr[i] represents the total candies received by the ith person.
Examples:
Input: n = 7, k = 4
Output: [1, 2, 3, 1]
Explanation: The first person receives 1 candy, the second receives 2 candies, and the third receives 3 candies. Only 1 candy remains for the fourth person, so they receive the remaining candy. Therefore, the final distribution is [1, 2, 3, 1].
Input: n = 10, k = 3
Output: [5, 2, 3]
Explanation: In the first round, the three people receive 1, 2, and 3 candies respectively. In the next round, the first person receives 4 candies, exhausting all the remaining candies. Therefore, the final distribution is [5, 2, 3].
Table of Content
[Naive Approach] Simple Simulation - O(sqrt(n)) Time and O(k) Space
This directly simulates the distribution process.
Start distributing candies one by one according to the problem statement. Give 1 candy to the first person, 2 candies to the second person, and so on. If the remaining candies are fewer than the required amount, give all remaining candies to the current person and stop.
#include <iostream>
#include <vector>
using namespace std;
vector<int> distributeCandies(int n, int k) {
vector<int> arr(k, 0);
int give = 1;
int idx = 0;
while (n > 0) {
arr[idx] += min(give, n);
n -= min(give, n);
give++;
idx = (idx + 1) % k;
}
return arr;
}
int main() {
vector<int> res = distributeCandies(7, 4);
for (int x : res) cout << x << " ";
cout << endl;
res = distributeCandies(10, 3);
for (int x : res) cout << x << " ";
return 0;
}
import java.util.ArrayList;
class GFG {
static ArrayList<Integer> distributeCandies(int n, int k) {
ArrayList<Integer> arr = new ArrayList<>();
for (int i = 0; i < k; i++) {
arr.add(0);
}
int give = 1;
int idx = 0;
while (n > 0) {
int candies = Math.min(give, n);
arr.set(idx, arr.get(idx) + candies);
n -= candies;
give++;
idx = (idx + 1) % k;
}
return arr;
}
public static void main(String[] args) {
System.out.println(distributeCandies(7, 4));
System.out.println(distributeCandies(10, 3));
}
}
def distributeCandies(n, k):
arr = [0] * k
give = 1
idx = 0
while n > 0:
candies = min(give, n)
arr[idx] += candies
n -= candies
give += 1
idx = (idx + 1) % k
return arr
if __name__ == "__main__":
print(distributeCandies(7, 4))
print(distributeCandies(10, 3))
using System;
using System.Collections.Generic;
class GFG {
static List<int> distributeCandies(int n, int k) {
List<int> arr = new List<int>();
for (int i = 0; i < k; i++) {
arr.Add(0);
}
int give = 1;
int idx = 0;
while (n > 0) {
int candies = Math.Min(give, n);
arr[idx] += candies;
n -= candies;
give++;
idx = (idx + 1) % k;
}
return arr;
}
static void Main() {
Console.WriteLine(string.Join(" ", distributeCandies(7, 4)));
Console.WriteLine(string.Join(" ", distributeCandies(10, 3)));
}
}
function distributeCandies(n, k) {
let arr = new Array(k).fill(0);
let give = 1;
let idx = 0;
while (n > 0) {
let candies = Math.min(give, n);
arr[idx] += candies;
n -= candies;
give++;
idx = (idx + 1) % k;
}
return arr;
}
// Driver Code
console.log(distributeCandies(7, 4).join(" "));
console.log(distributeCandies(10, 3).join(" "));
Output
1 2 3 1 5 2 3
[Expected Approach] Using Binary Search - O(log n + k) Time + O(k) Space
The idea is to find how many complete distributions can be made. If x distributions have been made, then the total candies used are: x * (x + 1) / 2
Use binary search to find the maximum x such that this value does not exceed n.
After determining the number of complete distributions, distribute the remaining candies and compute each person's contribution directly using arithmetic progression formulas.
#include <iostream>
#include <vector>
using namespace std;
vector<int> distributeCandies(int n, int k) {
vector<int> arr(k, 0);
int low = 0, high = n;
int count = 0;
// Find the maximum number of complete distributions.
while (low <= high) {
int mid = low + (high - low) / 2;
long long total = 1LL * mid * (mid + 1) / 2;
if (total <= n) {
count = mid / k;
low = mid + 1;
} else {
high = mid - 1;
}
}
int last = count * k;
n -= (int)(1LL * last * (last + 1) / 2);
int term = last + 1;
int idx = 0;
while (n > 0) {
if (term <= n) {
arr[idx] = term;
n -= term;
term++;
idx++;
} else {
arr[idx] += n;
n = 0;
}
}
for (int i = 0; i < k; i++) {
arr[i] += count * (i + 1)
+ k * count * (count - 1) / 2;
}
return arr;
}
int main() {
vector<int> res = distributeCandies(7, 4);
for (int x : res) cout << x << " ";
cout << endl;
res = distributeCandies(10, 3);
for (int x : res) cout << x << " ";
return 0;
}
import java.util.ArrayList;
class GFG {
static ArrayList<Integer> distributeCandies(int n, int k) {
ArrayList<Integer> arr = new ArrayList<>();
for (int i = 0; i < k; i++) {
arr.add(0);
}
int low = 0, high = n;
int count = 0;
// Find the maximum number of complete distributions.
while (low <= high) {
int mid = low + (high - low) / 2;
long total = 1L * mid * (mid + 1) / 2;
if (total <= n) {
count = mid / k;
low = mid + 1;
} else {
high = mid - 1;
}
}
int last = count * k;
n -= (int)(1L * last * (last + 1) / 2);
int term = last + 1;
int idx = 0;
while (n > 0) {
if (term <= n) {
arr.set(idx, term);
n -= term;
term++;
idx++;
} else {
arr.set(idx, arr.get(idx) + n);
n = 0;
}
}
for (int i = 0; i < k; i++) {
arr.set(
i,
arr.get(i)
+ count * (i + 1)
+ k * count * (count - 1) / 2
);
}
return arr;
}
public static void main(String[] args) {
System.out.println(distributeCandies(7, 4));
System.out.println(distributeCandies(10, 3));
}
}
def distributeCandies(n, k):
arr = [0] * k
low, high = 0, n
count = 0
# Find the maximum number of complete distributions.
while low <= high:
mid = low + (high - low) // 2
total = mid * (mid + 1) // 2
if total <= n:
count = mid // k
low = mid + 1
else:
high = mid - 1
last = count * k
n -= last * (last + 1) // 2
term = last + 1
idx = 0
while n > 0:
if term <= n:
arr[idx] = term
n -= term
term += 1
idx += 1
else:
arr[idx] += n
n = 0
for i in range(k):
arr[i] += (
count * (i + 1)
+ k * count * (count - 1) // 2
)
return arr
if __name__ == "__main__":
print(distributeCandies(7, 4))
print(distributeCandies(10, 3))
using System;
using System.Collections.Generic;
class GFG {
static List<int> distributeCandies(int n, int k) {
List<int> arr = new List<int>();
for (int i = 0; i < k; i++) {
arr.Add(0);
}
int low = 0, high = n;
int count = 0;
// Find the maximum number of complete distributions.
while (low <= high) {
int mid = low + (high - low) / 2;
long total = 1L * mid * (mid + 1) / 2;
if (total <= n) {
count = mid / k;
low = mid + 1;
} else {
high = mid - 1;
}
}
int last = count * k;
n -= (int)(1L * last * (last + 1) / 2);
int term = last + 1;
int idx = 0;
while (n > 0) {
if (term <= n) {
arr[idx] = term;
n -= term;
term++;
idx++;
} else {
arr[idx] += n;
n = 0;
}
}
for (int i = 0; i < k; i++) {
arr[i] += count * (i + 1)
+ k * count * (count - 1) / 2;
}
return arr;
}
static void Main() {
Console.WriteLine(string.Join(" ", distributeCandies(7, 4)));
Console.WriteLine(string.Join(" ", distributeCandies(10, 3)));
}
}
function distributeCandies(n, k) {
let arr = new Array(k).fill(0);
let low = 0, high = n;
let count = 0;
// Find the maximum number of complete distributions.
while (low <= high) {
let mid = low + Math.floor((high - low) / 2);
let total = Math.floor(mid * (mid + 1) / 2);
if (total <= n) {
count = Math.floor(mid / k);
low = mid + 1;
} else {
high = mid - 1;
}
}
let last = count * k;
n -= Math.floor(last * (last + 1) / 2);
let term = last + 1;
let idx = 0;
while (n > 0) {
if (term <= n) {
arr[idx] = term;
n -= term;
term++;
idx++;
} else {
arr[idx] += n;
n = 0;
}
}
for (let i = 0; i < k; i++) {
arr[i] += count * (i + 1)
+ Math.floor(k * count * (count - 1) / 2);
}
return arr;
}
// Driver Code
console.log(distributeCandies(7, 4).join(" "));
console.log(distributeCandies(10, 3).join(" "));
Output
1 2 3 1 5 2 3