Given an array prices[] of n different candies, where prices[i] represents the price of the ith candy and all prices are distinct. The store has an offer where for every candy you buy, you can get up to k other different candies for free. Find the minimum and maximum amount of money needed to buy all the candies.
Note: In both cases, you must take the maximum number of free candies possible during each purchase.
Examples:
Input: prices[] = [3, 2, 1, 4], k = 2
Output: [3, 7]
Explanation: For minimum cost, buy the candies costing 1 and 2. for maximum cost, buy the candies costing 4 and 3.Input: prices[] = [3, 2, 1, 4, 5], k = 4
Output: [1, 5]
Explanation: For minimum cost, buy the candy costing 1. for maximum cost, buy the candy costing 5.
Approach - Using Sorting - O(n log(n)) Time and O(1) Space
The idea is to minimize the cost by buying the cheapest candies and taking the most expensive ones for free, and to maximize the cost by buying the most expensive candies and taking the cheapest ones for free.
Step By Step Implementations:
- Sort the prices array in ascending order to access the cheapest and most expensive candies easily.
- For minimum cost
-> use a pointer i starting from the beginning and a variable n for the total candies.
-> in each step, buy the candy at i (add to minCost) and move i forward.
-> reduce n by k to simulate getting up to k candies for free. - For maximum cost
-> use a pointer i starting from the end and an index marker initialized to -1.
-> in each step, buy the candy at i (add to maxCost) and move i backward.
-> increase index by k to simulate taking free candies. - Return both minCost and maxCost as the final result.
Illustrations:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> minMaxCandy(vector<int>& prices, int k) {
// Sort the array to arrange candies by price
sort(prices.begin(), prices.end());
// Calculate minimum cost by traversing from beginning
int n = prices.size();
int minCost = 0;
for (int i = 0; i < n; i++) {
minCost += prices[i];
n -= k;
}
// Calculate maximum cost by traversing from end
int index = -1, maxCost = 0;
for (int i = prices.size() - 1; i > index; i--) {
maxCost += prices[i];
index += k;
}
return {minCost, maxCost};
}
int main() {
vector<int> prices = {3, 2, 1, 4};
int k = 2;
vector<int> res = minMaxCandy(prices, k);
cout << res[0] << " " << res[1] << endl;
return 0;
}
import java.util.ArrayList;
import java.util.Arrays;
public class GfG {
static ArrayList<Integer> minMaxCandy(int[] prices, int k) {
// Sort the array to arrange candies by price
Arrays.sort(prices);
// Calculate minimum cost by traversing
// from beginning
int n = prices.length;
int minCost = 0;
for (int i = 0; i < n; i++) {
minCost += prices[i];
n -= k;
}
// Calculate maximum cost by traversing
// from end
int index = -1, maxCost = 0;
for (int i = prices.length - 1; i > index; i--) {
maxCost += prices[i]; // fixed here
index += k;
}
ArrayList<Integer> result = new ArrayList<>();
result.add(minCost);
result.add(maxCost);
return result;
}
public static void main(String[] args) {
int[] prices = {3, 2, 1, 4};
int k = 2;
ArrayList<Integer> res = minMaxCandy(prices, k);
System.out.println(res.get(0) + " " + res.get(1));
}
}
def minMaxCandy(prices, k):
# Sort the array to arrange candies by price
prices.sort()
n = len(prices)
# Calculate minimum cost
minCost = 0
i, end = 0, n - 1
while i <= end:
minCost += prices[i]
i += 1
# seller gives k candies for free from the end
end -= k
# Calculate maximum cost
maxCost = 0
i, start = n - 1, 0
while i >= start:
maxCost += prices[i]
i -= 1
# seller gives k cheapest candies for free
start += k
return [minCost, maxCost]
if __name__ == '__main__':
prices = [3, 2, 1, 4]
k = 2
res = minMaxCandy(prices, k)
print(res[0], res[1])
using System;
using System.Linq;
using System.Collections.Generic;
public class GfG {
static List<int> minMaxCandy(int[] prices, int k) {
// Sort prices in ascending order
Array.Sort(prices);
int n = prices.Length;
// Calculate minimum cost
int minCost = 0;
int i = 0, end = n - 1;
while (i <= end) {
minCost += prices[i];
i++;
// seller gives k candies from the end for free
end -= k;
}
// Calculate maximum cost
int maxCost = 0;
int start = 0;
i = n - 1;
while (i >= start) {
maxCost += prices[i];
i--;
// seller gives k cheapest candies for free
start += k;
}
return new List<int> { minCost, maxCost };
}
public static void Main(string[] args) {
int[] prices = { 3, 2, 1, 4 };
int k = 2;
List<int> res = minMaxCandy(prices, k);
Console.WriteLine(res[0] + " " + res[1]);
}
}
function minMaxCandy(prices, k) {
// Sort prices in ascending order
prices.sort((a, b) => a - b);
let n = prices.length;
// Calculate minimum cost
let minCost = 0;
let i = 0, end = n - 1;
while (i <= end) {
minCost += prices[i];
i++;
// get k most expensive candies for free
end -= k;
}
// Calculate maximum cost
let maxCost = 0;
let start = 0;
i = n - 1;
while (i >= start) {
maxCost += prices[i];
i--;
// get k cheapest candies for free
start += k;
}
return [minCost, maxCost];
}
// Driver Code
const prices = [3, 2, 1, 4];
const k = 2;
const res = minMaxCandy(prices, k);
console.log(res[0] + ' ' + res[1]);
<?php
// PHP implementation to find the minimum
// and maximum amount
// Function to find the minimum amount
// to buy all candies
function findMinimum($prices, $n, $k)
{
$res = 0;
for ($i = 0; $i < $n; $i++)
{
// Buy current candy
$res += $prices[$i];
// And take k candies for free from the last
$n = $n - $k;
}
return $res;
}
// Function to find the maximum amount
// to buy all candies
function findMaximum($prices, $n, $k)
{
$res = 0;
$index = 0;
for ($i = $n - 1; $i >= $index; $i--)
{
// Buy candy with maximum amount
$res += $prices[$i];
// And get k candies for free from the start
$index += $k;
}
return $res;
}
// Driver Code
$prices = array(3, 2, 1, 4);
$n = sizeof($prices);
$k = 2;
sort($prices);
// Function call
echo findMinimum($prices, $n, $k) . " " . findMaximum($prices, $n, $k);
?>
Output
3 7