Wine Buying and Selling

Last Updated : 1 Jul, 2026

Given an integer array arr[] representing houses built along a straight line, each value arr[i] represents a certain number of wine bottles that a wants to buy or sell.

  • If arr[i] < 0, then the i-th house wants to sell |arr[i]| bottles of wine.
  • If arr[i] > 0, then the i-th house wants to buy arr[i] bottles of wine.

Find the minimum total work required so that all houses can fulfill their wine buy/sell requirements.

  • Transporting one bottle of wine from one house to an adjacent house costs 1 unit of work.
  • It is guaranteed that the sum of all elements of the array is 0.

Examples:

Input: arr[] = [5, -4, 1, -3, 1]
Output: 9
Explanation: 
House 1 sells 4 bottles to house 0, so work done is 4 × 1 = 4.
Updated array becomes: [1, 0, 1, -3, 1]
Now, house 3 sells:
1 bottle to house 0 -> work = 3
1 bottle to house 2 -> work = 1
1 bottle to house 4 -> work = 1
Total additional work = 3 + 1 + 1 = 5
Hence, total minimum work = 4 + 5 = 9.
So the answer for this test case is 9.

Input: arr[] = [-1000, -1000, -1000, 1000, 1000, 1000]
Output: 9000
Explanation: 
House 0 sells 1000 bottles to house 3 -> work = 1000 × 3 = 3000
House 1 sells 1000 bottles to house 4 -> work = 1000 × 3 = 3000
House 2 sells 1000 bottles to house 5 -> work = 1000 × 3 = 3000
Total minimum work = 3000 + 3000 + 3000 = 9000.
So the answer for this test case is 9000.

Try It Yourself
redirect icon

[Naive Approach] Simulate Every Wine Transfer - O(n ^ 2) Time and O(1) Space

The idea is to process each seller and search for buyers one by one, transferring as many bottles as possible until all wine requirements are fulfilled.

C++
#include <iostream>
#include <vector>
using namespace std;

int wineSelling(vector<int> &arr)
{
    int n = arr.size();
    int res = 0;

    // Process each seller
    for (int i = 0; i < n; i++)
    {
        // Skip non-sellers
        if (arr[i] >= 0)
            continue;

        int need = -arr[i];

        // Search for buyers
        for (int j = 0; j < n && need > 0; j++)
        {
            // Skip non-buyers
            if (arr[j] <= 0)
                continue;

            // Transfer the maximum possible bottles
            int x = min(need, arr[j]);

            // Add the work required for this transfer
            res += x * abs(i - j);

            need -= x;
            arr[j] -= x;
        }
    }

    return res;
}

int main()
{
    vector<int> arr = {-1000, -1000, -1000, 1000, 1000, 1000};

    cout << wineSelling(arr);

    return 0;
}
Java
import java.util.Arrays;

public class GFG {
    public static int wineSelling(int[] arr)
    {
        int n = arr.length;
        int res = 0;

        // Process each seller
        for (int i = 0; i < n; i++) {
            // Skip non-sellers
            if (arr[i] >= 0)
                continue;

            int need = -arr[i];

            // Search for buyers
            for (int j = 0; j < n && need > 0; j++) {
                // Skip non-buyers
                if (arr[j] <= 0)
                    continue;

                // Transfer the maximum possible bottles
                int x = Math.min(need, arr[j]);

                // Add the work required for this transfer
                res += x * Math.abs(i - j);

                need -= x;
                arr[j] -= x;
            }
        }

        return res;
    }

    public static void main(String[] args)
    {
        int[] arr
            = { -1000, -1000, -1000, 1000, 1000, 1000 };

        System.out.println(wineSelling(arr));
    }
}
Python
def wineSelling(arr):
    n = len(arr)
    res = 0

    # Process each seller
    for i in range(n):
        # Skip non-sellers
        if arr[i] >= 0:
            continue

        need = -arr[i]

        # Search for buyers
        for j in range(n):
            if need <= 0:
                break

            # Skip non-buyers
            if arr[j] <= 0:
                continue

            # Transfer the maximum possible bottles
            x = min(need, arr[j])

            # Add the work required for this transfer
            res += x * abs(i - j)

            need -= x
            arr[j] -= x

    return res


if __name__ == "__main__":
    arr = [-1000, -1000, -1000, 1000, 1000, 1000]

    print(wineSelling(arr))
C#
using System;
using System.Collections.Generic;

public class GFG {
    public static int wineSelling(List<int> arr)
    {
        int n = arr.Count;
        int res = 0;

        // Process each seller
        for (int i = 0; i < n; i++) {
            // Skip non-sellers
            if (arr[i] >= 0)
                continue;

            int need = -arr[i];

            // Search for buyers
            for (int j = 0; j < n && need > 0; j++) {
                // Skip non-buyers
                if (arr[j] <= 0)
                    continue;

                // Transfer the maximum possible bottles
                int x = Math.Min(need, arr[j]);

                // Add the work required for this transfer
                res += x * Math.Abs(i - j);

                need -= x;
                arr[j] -= x;
            }
        }

        return res;
    }

    public static void Main()
    {
        List<int> arr = new List<int>{ -1000, -1000, -1000,
                                       1000,  1000,  1000 };

        Console.WriteLine(wineSelling(arr));
    }
}
JavaScript
function wineSelling(arr)
{
    let n = arr.length;
    let res = 0;

    // Process each seller
    for (let i = 0; i < n; i++) {
        // Skip non-sellers
        if (arr[i] >= 0)
            continue;

        let need = -arr[i];

        // Search for buyers
        for (let j = 0; j < n && need > 0; j++) {
            // Skip non-buyers
            if (arr[j] <= 0)
                continue;

            // Transfer the maximum possible bottles
            let x = Math.min(need, arr[j]);

            // Add the work required for this transfer
            res += x * Math.abs(i - j);

            need -= x;
            arr[j] -= x;
        }
    }

    return res;
}

let arr = [ -1000, -1000, -1000, 1000, 1000, 1000 ];

console.log(wineSelling(arr));

Output
9000

[Expected Approach - 1] Simulating Wine Transfers Using Two Pointers - O(n) Time and O(n) Space

The idea is to store all buyers and sellers separately and use two pointers to match them. Transfer the maximum possible bottles at each step and add the corresponding work.

Let us understand with an example:
Input: arr[] = [-1000, -1000, -1000, 1000, 1000, 1000]

  • Store all buyers and sellers along with their indices: buy = {(1000, 3), (1000, 4), (1000, 5)} and sell = {(1000, 0), (1000, 1), (1000, 2)}. Initialize i = 0, j = 0, and res = 0.
  • Match seller (1000, 0) with buyer (1000, 3). Transfer 1000 bottles, so work = 1000 × (3 - 0) = 3000. Update res = 3000 and move both pointers.
  • Match seller (1000, 1) with buyer (1000, 4). Transfer 1000 bottles, so work = 1000 × (4 - 1) = 3000. Update res = 6000 and move both pointers.
  • Match seller (1000, 2) with buyer (1000, 5). Transfer 1000 bottles, so work = 1000 × (5 - 2) = 3000. Update res = 9000 and move both pointers.
  • Both buyer and seller lists are exhausted, so the algorithm terminates and returns 9000.
C++
#include <iostream>
#include <vector>
using namespace std;

int wineSelling(vector<int> &arr)
{
    int n = arr.size();

    vector<pair<int, int>> buy;
    vector<pair<int, int>> sell;

    // Store buyers and sellers
    for (int i = 0; i < n; i++)
    {
        if (arr[i] > 0)
            buy.push_back({arr[i], i});

        else if (arr[i] < 0)
            sell.push_back({-arr[i], i});
    }

    int i = 0, j = 0;
    int res = 0;

    // Match buyers and sellers
    while (i < buy.size() && j < sell.size())
    {
        // Transfer the maximum possible bottles
        int x = min(buy[i].first, sell[j].first);

        // Add the work required for this transfer
        res += x * abs(buy[i].second - sell[j].second);

        buy[i].first -= x;
        sell[j].first -= x;

        // Move to the next buyer if satisfied
        if (buy[i].first == 0)
            i++;

        // Move to the next seller if satisfied
        if (sell[j].first == 0)
            j++;
    }

    return res;
}

int main()
{
    vector<int> arr = {-1000, -1000, -1000, 1000, 1000, 1000};

    cout << wineSelling(arr);

    return 0;
}
Java
import java.util.ArrayList;
import java.util.List;

public class GFG {
    public static int wineSelling(int[] arr)
    {
        int n = arr.length;

        List<int[]> buy = new ArrayList<>();
        List<int[]> sell = new ArrayList<>();

        // Store buyers and sellers
        for (int i = 0; i < n; i++) {
            if (arr[i] > 0)
                buy.add(new int[] { arr[i], i });

            else if (arr[i] < 0)
                sell.add(new int[] { -arr[i], i });
        }

        int i = 0, j = 0;
        int res = 0;

        // Match buyers and sellers
        while (i < buy.size() && j < sell.size()) {
            // Transfer the maximum possible bottles
            int x = Math.min(buy.get(i)[0], sell.get(j)[0]);

            // Add the work required for this transfer
            res += x
                   * Math.abs(buy.get(i)[1]
                              - sell.get(j)[1]);

            buy.get(i)[0] -= x;
            sell.get(j)[0] -= x;

            // Move to the next buyer if satisfied
            if (buy.get(i)[0] == 0)
                i++;

            // Move to the next seller if satisfied
            if (sell.get(j)[0] == 0)
                j++;
        }

        return res;
    }

    public static void main(String[] args)
    {
        int[] arr
            = { -1000, -1000, -1000, 1000, 1000, 1000 };

        System.out.println(wineSelling(arr));
    }
}
Python
def wineSelling(arr):
    n = len(arr)

    buy = []
    sell = []

    # Store buyers and sellers
    for i in range(n):
        if arr[i] > 0:
            buy.append([arr[i], i])
        elif arr[i] < 0:
            sell.append([-arr[i], i])

    i = 0
    j = 0
    res = 0

    # Match buyers and sellers
    while i < len(buy) and j < len(sell):
        # Transfer the maximum possible bottles
        x = min(buy[i][0], sell[j][0])

        # Add the work required for this transfer
        res += x * abs(buy[i][1] - sell[j][1])

        buy[i][0] -= x
        sell[j][0] -= x

        # Move to the next buyer if satisfied
        if buy[i][0] == 0:
            i += 1

        # Move to the next seller if satisfied
        if sell[j][0] == 0:
            j += 1

    return res


if __name__ == '__main__':
    arr = [-1000, -1000, -1000, 1000, 1000, 1000]
    print(wineSelling(arr))
C#
using System;
using System.Collections.Generic;

public class GFG {
    public static int wineSelling(List<int> arr)
    {
        int n = arr.Count;

        List<Tuple<int, int> > buy
            = new List<Tuple<int, int> >();
        List<Tuple<int, int> > sell
            = new List<Tuple<int, int> >();

        // Store buyers and sellers
        for (int i = 0; i < n; i++) {
            if (arr[i] > 0)
                buy.Add(new Tuple<int, int>(arr[i], i));

            else if (arr[i] < 0)
                sell.Add(new Tuple<int, int>(-arr[i], i));
        }

        int left = 0, right = 0;
        int res = 0;

        // Match buyers and sellers
        while (left < buy.Count && right < sell.Count) {
            // Transfer the maximum possible bottles
            int x = Math.Min(buy[left].Item1,
                             sell[right].Item1);

            // Add the work required for this transfer
            res += x
                   * Math.Abs(buy[left].Item2
                              - sell[right].Item2);

            buy[left] = new Tuple<int, int>(
                buy[left].Item1 - x, buy[left].Item2);
            sell[right] = new Tuple<int, int>(
                sell[right].Item1 - x, sell[right].Item2);

            // Move to the next buyer if satisfied
            if (buy[left].Item1 == 0)
                left++;

            // Move to the next seller if satisfied
            if (sell[right].Item1 == 0)
                right++;
        }

        return res;
    }

    public static void Main()
    {
        List<int> arr = new List<int>{ -1000, -1000, -1000,
                                       1000,  1000,  1000 };

        Console.WriteLine(wineSelling(arr));
    }
}
JavaScript
function wineSelling(arr)
{
    let n = arr.length;

    let buy = [];
    let sell = [];

    // Store buyers and sellers
    for (let i = 0; i < n; i++) {
        if (arr[i] > 0)
            buy.push([ arr[i], i ]);

        else if (arr[i] < 0)
            sell.push([ -arr[i], i ]);
    }

    let i = 0, j = 0;
    let res = 0;

    // Match buyers and sellers
    while (i < buy.length && j < sell.length) {
        // Transfer the maximum possible bottles
        let x = Math.min(buy[i][0], sell[j][0]);

        // Add the work required for this transfer
        res += x * Math.abs(buy[i][1] - sell[j][1]);

        buy[i][0] -= x;
        sell[j][0] -= x;

        // Move to the next buyer if satisfied
        if (buy[i][0] == 0)
            i++;

        // Move to the next seller if satisfied
        if (sell[j][0] == 0)
            j++;
    }

    return res;
}

let arr = [ -1000, -1000, -1000, 1000, 1000, 1000 ];
console.log(wineSelling(arr));

Output
9000

[Expected Approach - 2] Prefix Balance - O(n) Time and O(1) Space

The idea is to maintain the cumulative wine balance while traversing the houses. The absolute value of the balance at each position contributes to the minimum work.

Let us understand with an example:
Input: arr[] = [-1000, -1000, -1000, 1000, 1000, 1000]

  • Initialize balance = 0 and res = 0.
  • Process -1000: balance = -1000, so res += |-1000| = 1000. Process the next -1000: balance = -2000, res = 3000. Process the next -1000: balance = -3000, res = 6000.
  • Process 1000: balance = -2000, so res = 8000. Process the next 1000: balance = -1000, res = 9000.
  • Process the last 1000: balance = 0, so res += |0| = 0. Thus, res remains 9000.
  • After traversing all houses, the algorithm returns 9000, which is the minimum total work required.
C++
#include <iostream>
#include <vector>
using namespace std;

int wineSelling(vector<int> &arr)
{

    int balance = 0;
    int res = 0;

    // Traverse all houses
    for (int x : arr)
    {

        balance += x;

        // Add work contributed by the current balance
        res += abs(balance);
    }

    return res;
}

int main()
{

    vector<int> arr = {-1000, -1000, -1000, 1000, 1000, 1000};

    cout << wineSelling(arr);

    return 0;
}
Java
import java.util.ArrayList;

public class GFG {
    public static int wineSelling(ArrayList<Integer> arr)
    {
        int balance = 0;
        int res = 0;

        // Traverse all houses
        for (int x : arr) {
            balance += x;

            // Add work contributed by the current balance
            res += Math.abs(balance);
        }

        return res;
    }

    public static void main(String[] args)
    {
        ArrayList<Integer> arr = new ArrayList<>();
        arr.add(-1000);
        arr.add(-1000);
        arr.add(-1000);
        arr.add(1000);
        arr.add(1000);
        arr.add(1000);

        System.out.println(wineSelling(arr));
    }
}
Python
def wineSelling(arr):
    balance = 0
    res = 0

    # Traverse all houses
    for x in arr:
        balance += x

        # Add work contributed by the current balance
        res += abs(balance)

    return res


if __name__ == '__main__':
    arr = [-1000, -1000, -1000, 1000, 1000, 1000]
    print(wineSelling(arr))
C#
using System;
using System.Collections.Generic;

public class GFG {
    public static int wineSelling(List<int> arr)
    {
        int balance = 0;
        int res = 0;

        // Traverse all houses
        foreach(int x in arr)
        {
            balance += x;

            // Add work contributed by the current balance
            res += Math.Abs(balance);
        }

        return res;
    }

    public static void Main()
    {
        List<int> arr = new List<int>{ -1000, -1000, -1000,
                                       1000,  1000,  1000 };
        Console.WriteLine(wineSelling(arr));
    }
}
JavaScript
function wineSelling(arr)
{
    let balance = 0;
    let res = 0;

    // Traverse all houses
    for (let x of arr) {
        balance += x;

        // Add work contributed by the current balance
        res += Math.abs(balance);
    }

    return res;
}

const arr = [ -1000, -1000, -1000, 1000, 1000, 1000 ];
console.log(wineSelling(arr));

Output
9000
Comment