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.
**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:
- Divide array into two equal parts.
- Generate all subsets and for each subset calculate **product of elements and **store this to a container. Try this for both part of array.
- **Sort both container which contains **products of elements for each possible subsets.
- Traverse any one container and find **upper-bound of element to find how many subsets are there whose **product of elements is **less than k.
**Some key points to improve complexity:
- Ignore elements from array if **greater than k.
- Ignore **product of elements to push into container(subset1 or subset2) if **greater than k. C++ `
// 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 countif 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.