Number of subsets with product less than k (original) (raw)

Last Updated : 11 Jul, 2025

Given an array **arr[] of **n elements. The task is to find the number of non-empty subsets whose **product of elements is less than or equal to a given integer **k.

**Examples:

**Input: arr[] = [2, 4, 5, 3], k = 12
**Output: 8
**Explanation: All possible subsets whose products are less than 12 are: (2), (4), (5), (3), (2, 4), (2, 5), (2, 3), (4, 3)

**Input: arr[] = [9, 8, 3], k = 2
**Output: 0
**Explanation: There are no subsets with products less than or equal to 2.

Try It Yourselfredirect icon

**Using meet in middle approach - O(n*2 n/2 ) time and O(2 n/2 ) space

First of all, we simply **divide the given array into two equal parts and after that, we **generate all **possible subsets for both parts of the array and store the value of the elements **product for each subset separately into two containers ****(say subset1 & subset2).** Then we combine the **results of two halves to give a final answer. This technique is generally referred to as meet in the middle.

**Algorithm:

**Some key points to improve complexity:

// A C++ program to find the count subset having product // less than k #include <bits/stdc++.h> using namespace std;

int numOfSubsets(vector &arr, int k) {

int n = arr.size();

// declare four vector for dividing array into
// two halves and storing product value of
// possible subsets for them
vector<int> vect1, vect2, subset1, subset2;

// ignore element greater than k and divide
// array into 2 halves
for (int i = 0; i < n; i++) {

    // ignore element if greater than k
    if (arr[i] > k)
        continue;
    if (i <= n / 2)
        vect1.push_back(arr[i]);
    else
        vect2.push_back(arr[i]);
}

// generate all subsets for 1st half (vect1)
for (int i = 0; i < (1 << vect1.size()); i++) {
    int value = 1;
    for (int j = 0; j < vect1.size() and value <= k; j++) {
        if (i & (1 << j))
            value *= vect1[j];
    }

    // push only in case subset product is less
    // than equal to k
    if (value <= k)
        subset1.push_back(value);
}

// generate all subsets for 2nd half (vect2)
for (int i = 0; i < (1 << vect2.size()); i++) {
    int value = 1;
    for (int j = 0; j < vect2.size() and value <= k; j++) {
        if (i & (1 << j))
            value *= vect2[j];
    }

    // push only in case subset product is
    // less than equal to k
    if (value <= k)
        subset2.push_back(value);
}

// sort subset2
sort(subset2.begin(), subset2.end());

int count = 0;
for (int i = 0; i < subset1.size(); i++)
    count += upper_bound(subset2.begin(), subset2.end(), 
                (k / subset1[i])) - subset2.begin();

// for null subset decrement the
  // value of count
count--;

return count;

}

int main() { vector arr = {4, 2, 3, 6, 5}; int k = 25; cout << numOfSubsets(arr, k); return 0; }

Java

// A java program to find the count subset having product // less than k

import java.util.*;

class GfG {

static int numOfSubsets(List<Integer> arr, int k) {
    int n = arr.size();

    // Declare four lists for dividing array into
    // two halves and storing product values of
    // possible subsets for them
    List<Integer> vect1 = new ArrayList<>();
    List<Integer> vect2 = new ArrayList<>();
    List<Integer> subset1 = new ArrayList<>();
    List<Integer> subset2 = new ArrayList<>();

    // Ignore elements greater than k and divide
    // array into 2 halves
    for (int i = 0; i < n; i++) {

        // Ignore element if greater than k
        if (arr.get(i) > k)
            continue;
        if (i <= n / 2)
            vect1.add(arr.get(i));
        else
            vect2.add(arr.get(i));
    }

    // Generate all subsets for 1st half (vect1)
    for (int i = 0; i < (1 << vect1.size()); i++) {
        int value = 1;
        for (int j = 0; j < vect1.size() && value <= k;
             j++) {
            if ((i & (1 << j)) != 0)
                value *= vect1.get(j);
        }

        // Add only if subset product is less than or
        // equal to k
        if (value <= k)
            subset1.add(value);
    }

    // Generate all subsets for 2nd half (vect2)
    for (int i = 0; i < (1 << vect2.size()); i++) {
        int value = 1;
        for (int j = 0; j < vect2.size() && value <= k;
             j++) {
            if ((i & (1 << j)) != 0)
                value *= vect2.get(j);
        }

        // Add only if subset product is less than or
        // equal to k
        if (value <= k)
            subset2.add(value);
    }

    // Sort subset2
    Collections.sort(subset2);

    int count = 0;
    for (int s1 : subset1) {
        count += upperBound(subset2, k / s1);
    }

    // For null subset decrement 
      // the value of count
    count--;

    return count;
}

// Helper function to find the upper bound index
static int upperBound(List<Integer> list, int value) {
    int low = 0, high = list.size();
    while (low < high) {
        int mid = (low + high) / 2;
        if (list.get(mid) <= value) {
            low = mid + 1;
        }
        else {
            high = mid;
        }
    }
    return low;
}

public static void main(String[] args) {
    List<Integer> arr = Arrays.asList(4, 2, 3, 6, 5);
    int k = 25;
    System.out.println(numOfSubsets(arr, k));
}

}

Python

Python to find the count subset

having product less than k

import bisect

def findSubset(arr, k):

# declare four vector for dividing
# array into two halves and storing
# product value of possible subsets
# for them
n = len(arr)
vect1, vect2, subset1, subset2 = [], [], [], []

# ignore element greater than k and
# divide array into 2 halves
for i in range(0, n):

    # ignore element if greater than k
    if arr[i] > k:
        continue
    if i <= n // 2:
        vect1.append(arr[i])
    else:
        vect2.append(arr[i])

# generate all subsets for 1st half (vect1)
for i in range(0, (1 << len(vect1))):
    value = 1
    for j in range(0, len(vect1)):
        if i & (1 << j):
            value *= vect1[j]

    # push only in case subset product
    # is less than equal to k
    if value <= k:
        subset1.append(value)

# generate all subsets for 2nd half (vect2)
for i in range(0, (1 << len(vect2))):
    value = 1
    for j in range(0, len(vect2)):
        if i & (1 << j):
            value *= vect2[j]

    # push only in case subset product
    # is less than equal to k
    if value <= k:
        subset2.append(value)

# sort subset2
subset2.sort()

count = 0
for i in range(0, len(subset1)):
    count += bisect.bisect(subset2, (k // subset1[i]))

# for null subset decrement the
# value of count
count -= 1
return count

if name == "main":

arr = [4, 2, 3, 6, 5]
k = 25
print(findSubset(arr, k))

C#

// A C# program to find the count subset having product // less than k

using System; using System.Collections.Generic;

class GfG {

// Function to find the count of subsets having product
// less than k
static int numOfSubsets(List<int> arr, int k) {

    int n = arr.Count;

    // Declare lists for dividing array into
    // two halves and storing product values of
    // possible subsets for them
    List<int> vect1 = new List<int>();
    List<int> vect2 = new List<int>();
    List<int> subset1 = new List<int>();
    List<int> subset2 = new List<int>();

    // Ignore elements greater than k and divide
    // array into 2 halves
    for (int i = 0; i < n; i++) {
        if (arr[i] > k)
            continue;
        if (i <= n / 2)
            vect1.Add(arr[i]);
        else
            vect2.Add(arr[i]);
    }

    // Generate all subsets for 1st half (vect1)
    for (int i = 0; i < (1 << vect1.Count); i++) {
        int value = 1;
        for (int j = 0; j < vect1.Count && value <= k;
             j++) {
            if ((i & (1 << j)) != 0)
                value *= vect1[j];
        }

        if (value <= k)
            subset1.Add(value);
    }

    // Generate all subsets for 2nd half (vect2)
    for (int i = 0; i < (1 << vect2.Count); i++) {
        int value = 1;
        for (int j = 0; j < vect2.Count && value <= k;
             j++) {
            if ((i & (1 << j)) != 0)
                value *= vect2[j];
        }

        if (value <= k)
            subset2.Add(value);
    }

    // Sort subset2
    subset2.Sort();

    int count = 0;
    foreach(int value in subset1) {
        count += BinarySearchUpperBound(subset2,
                                        k / value);
    }

    // For null subset decrement
      // the value of count
    count--;

    return count;
}

// Binary search to find the upper bound of value in
// subset2
static int BinarySearchUpperBound(List<int> list,
                                         int value) {
    int low = 0, high = list.Count;
    while (low < high) {
        int mid = (low + high) / 2;
        if (list[mid] <= value)
            low = mid + 1;
        else
            high = mid;
    }
    return low;
}

static void Main(string[] args) {
    List<int> arr = new List<int>{ 4, 2, 3, 6, 5 };
    int k = 25;
    Console.WriteLine(numOfSubsets(arr, k));
}

}

JavaScript

// A Javascript program to find the count subset having // product less than k

function binarySearchUpperBound(arr, value) { let low = 0, high = arr.length; while (low < high) { let mid = Math.floor((low + high) / 2); if (arr[mid] <= value) { low = mid + 1; } else { high = mid; } } return low; }

function numOfSubsets(arr, k) { let n = arr.length;

// Declare lists for dividing array into
// two halves and storing product values of
// possible subsets for them
let vect1 = [];
let vect2 = [];
let subset1 = [];
let subset2 = [];

// Ignore elements greater than k and divide
// array into 2 halves
for (let i = 0; i < n; i++) {
    if (arr[i] > k)
        continue;
    if (i <= Math.floor(n / 2)) {
        vect1.push(arr[i]);
    }
    else {
        vect2.push(arr[i]);
    }
}

// Generate all subsets for 1st half (vect1)
for (let i = 0; i < (1 << vect1.length); i++) {
    let value = 1;
    for (let j = 0; j < vect1.length && value <= k;
         j++) {
        if (i & (1 << j)) {
            value *= vect1[j];
        }
    }
    if (value <= k) {
        subset1.push(value);
    }
}

// Generate all subsets for 2nd half (vect2)
for (let i = 0; i < (1 << vect2.length); i++) {
    let value = 1;
    for (let j = 0; j < vect2.length && value <= k;
         j++) {
        if (i & (1 << j)) {
            value *= vect2[j];
        }
    }
    if (value <= k) {
        subset2.push(value);
    }
}

// Sort subset2
subset2.sort((a, b) => a - b);

let count = 0;
for (let value of subset1) {
    count += binarySearchUpperBound(
        subset2, Math.floor(k / value));
}

// For null subset decrement 
// the value of count
count--;

return count;

}

const arr = [ 4, 2, 3, 6, 5 ]; const k = 25; console.log(numOfSubsets(arr, k));

`

Please refer to Number of subsets with product less than k using DP for **Dynamic Programming solution.