Given an array arr[] consisting only of 1 and -1, and an integer k. The task is to determine whether there exists a subset of size k such that the sum of its elements is exactly 0. If such a subset exists, return true; otherwise, return false.
A subset is any selection of elements from an array, not necessarily contiguous, where the order does not matter. For example, for array [1, -1, 1], subsets of size 2 include [1, -1], [1, 1], and [-1, 1].
Examples:
Input: arr[] = [1, -1, 1, -1], k = 2
Output: true
Explanation: Subset [1, -1] has size 2 and sum 0.Input: arr[] = [1, 1, 1, -1], k = 3
Output: false
Explanation: Subset [1, 1, -1] has size 3 and sum 1. But [1, -1, 1] has sum 1 too. No subset of size 3 sums to 0. Hence, false.Input: arr[] = [1, -1, -1, 1, 1], k = 4
Output: true
Explanation: Subset [1, -1, -1, 1] has size 4 and sum 0.
Table of Content
[Approach - 1] Use Count of 1's and -1's - O(n) Time and O(1) Space
The idea is to use a simple counting strategy and a mathematical observation to determine if a subset of size k can sum to 0, without generating all subsets.
- In order for the sum to be 0, a subset must contain an equal number of 1's and -1's.
- If k is odd, it's impossible to divide k into two equal halves, so no subset can have a sum of 0.
- If k is even, we must select exactly k/2 elements with value 1 and k/2 elements with value -1 to achieve a balanced sum.
- Count the total number of 1's and -1's in the array.
- If the count of 1's is ≥ k/2 and the count of -1's is also ≥ k/2, then such a subset exists. So, return true.
- Otherwise, it's not possible to form a valid subset of size k with sum 0. So, return false.
// C++ program to check if there exists
// a subset of size k with sum 0
#include <iostream>
#include <vector>
using namespace std;
// Function to check if such a subset exists
bool isSubsetSumZero(vector<int> &arr, int k) {
int count1 = 0;
int countMinus1 = 0;
// Count number of 1's and -1's
for (int num : arr) {
if (num == 1) {
count1++;
} else if (num == -1) {
countMinus1++;
}
}
// If k is odd, it's impossible to
// divide into equal 1's and -1's
if (k % 2 != 0) {
return false;
}
int half = k / 2;
// Check if both 1's and -1's are enough
// to make a balanced subset
if (count1 >= half && countMinus1 >= half) {
return true;
}
return false;
}
// Driver code
int main() {
vector<int> arr = {1, -1, 1, -1};
int k = 2;
if (isSubsetSumZero(arr, k)) {
cout << "true";
} else {
cout << "false";
}
return 0;
}
// Java program to check if there exists
// a subset of size k with sum 0
class GfG {
// Function to check if such a subset exists
static boolean isSubsetSumZero(int[] arr, int k) {
int count1 = 0;
int countMinus1 = 0;
// Count number of 1's and -1's
for (int num : arr) {
if (num == 1) {
count1++;
} else if (num == -1) {
countMinus1++;
}
}
// If k is odd, it's impossible to
// divide into equal 1's and -1's
if (k % 2 != 0) {
return false;
}
int half = k / 2;
// Check if both 1's and -1's are enough
// to make a balanced subset
if (count1 >= half && countMinus1 >= half) {
return true;
}
return false;
}
public static void main(String[] args) {
int[] arr = {1, -1, 1, -1};
int k = 2;
if (isSubsetSumZero(arr, k)) {
System.out.print("true");
} else {
System.out.print("false");
}
}
}
# Python program to check if there exists
# a subset of size k with sum 0
def isSubsetSumZero(arr, k):
count1 = 0
countMinus1 = 0
# Count number of 1's and -1's
for num in arr:
if num == 1:
count1 += 1
elif num == -1:
countMinus1 += 1
# If k is odd, it's impossible to
# divide into equal 1's and -1's
if k % 2 != 0:
return False
half = k // 2
# Check if both 1's and -1's are enough
# to make a balanced subset
if count1 >= half and countMinus1 >= half:
return True
return False
if __name__ == "__main__":
arr = [1, -1, 1, -1]
k = 2
if isSubsetSumZero(arr, k):
print("true")
else:
print("false")
// C# program to check if there exists
// a subset of size k with sum 0
using System;
class GfG {
// Function to check if such a subset exists
public static bool isSubsetSumZero(int[] arr, int k) {
int count1 = 0;
int countMinus1 = 0;
// Count number of 1's and -1's
foreach (int num in arr) {
if (num == 1) {
count1++;
} else if (num == -1) {
countMinus1++;
}
}
// If k is odd, it's impossible to
// divide into equal 1's and -1's
if (k % 2 != 0) {
return false;
}
int half = k / 2;
// Check if both 1's and -1's are enough
// to make a balanced subset
if (count1 >= half && countMinus1 >= half) {
return true;
}
return false;
}
public static void Main(string[] args) {
int[] arr = {1, -1, 1, -1};
int k = 2;
if (isSubsetSumZero(arr, k)) {
Console.Write("true");
} else {
Console.Write("false");
}
}
}
// JavaScript program to check if there exists
// a subset of size k with sum 0
function isSubsetSumZero(arr, k) {
let count1 = 0;
let countMinus1 = 0;
// Count number of 1's and -1's
for (let num of arr) {
if (num === 1) {
count1++;
} else if (num === -1) {
countMinus1++;
}
}
// If k is odd, it's impossible to
// divide into equal 1's and -1's
if (k % 2 !== 0) {
return false;
}
let half = k / 2;
// Check if both 1's and -1's are enough
// to make a balanced subset
if (count1 >= half && countMinus1 >= half) {
return true;
}
return false;
}
// Driver Code
let arr = [1, -1, 1, -1];
let k = 2;
if (isSubsetSumZero(arr, k)) {
console.log("true");
} else {
console.log("false");
}
Output
true
[Approach - 2] Using Sliding Window (In Case of Subarray) - O(n) Time and O(1) Space
The idea is to use a sliding window of size k to scan through the array and keep track of the sum of the current window. The thought process is that if any subarray (contiguous subset) of size k has a sum of 0, it satisfies the condition.
Steps to implement the above idea:
- Initialize left, right, and sum to zero to start the sliding window traversal.
- Traverse the array using right pointer and keep adding elements to the current sum.
- Check if the current window size (right - left + 1) becomes equal to k.
- If the window size is k and the sum is zero, return true immediately.
- If the window size is k, remove arr[left] from sum and increment left to slide window.
- Keep moving the right pointer forward in each iteration until you reach the end of array.
- If no such window with sum zero is found, return false after the loop ends.
Note: The above sliding window approach only applies if the problem was asking for a subarray, not subset.
// C++ program to check if there exists
// a subarray of size k with sum 0
// using Sliding Window
#include <iostream>
#include <vector>
using namespace std;
// Function to check if such a subarray exists
bool isSubsetSumZero(vector<int> &arr, int k) {
int n = arr.size();
int left = 0, right = 0, sum = 0;
// Traverse the array using a sliding window
while (right < n) {
sum += arr[right];
// Check if window size is equal to k
if (right - left + 1 == k) {
// If sum of window is 0, subarray exists
if (sum == 0) {
return true;
}
// Slide the window by removing left element
sum -= arr[left];
left++;
}
right++;
}
return false;
}
// Driver code
int main() {
vector<int> arr = {1, -1, 1, -1};
int k = 2;
if (isSubsetSumZero(arr, k)) {
cout << "true";
} else {
cout << "false";
}
return 0;
}
// Java program to check if there exists
// a subarray of size k with sum 0
// using Sliding Window
class GfG {
// Function to check if such a subarray exists
static boolean isSubsetSumZero(int[] arr, int k) {
int n = arr.length;
int left = 0, right = 0, sum = 0;
// Traverse the array using a sliding window
while (right < n) {
sum += arr[right];
// Check if window size is equal to k
if (right - left + 1 == k) {
// If sum of window is 0, subarray exists
if (sum == 0) {
return true;
}
// Slide the window by removing left element
sum -= arr[left];
left++;
}
right++;
}
return false;
}
public static void main(String[] args) {
int[] arr = {1, -1, 1, -1};
int k = 2;
if (isSubsetSumZero(arr, k)) {
System.out.print("true");
} else {
System.out.print("false");
}
}
}
# Python program to check if there exists
# a subarray of size k with sum 0
# using Sliding Window
# Function to check if such a subarray exists
def isSubsetSumZero(arr, k):
n = len(arr)
left = 0
right = 0
sum = 0
# Traverse the array using a sliding window
while right < n:
sum += arr[right]
# Check if window size is equal to k
if right - left + 1 == k:
# If sum of window is 0, subarray exists
if sum == 0:
return True
# Slide the window by removing left element
sum -= arr[left]
left += 1
right += 1
return False
if __name__ == "__main__":
arr = [1, -1, 1, -1]
k = 2
if isSubsetSumZero(arr, k):
print("true")
else:
print("false")
// C# program to check if there exists
// a subarray of size k with sum 0
// using Sliding Window
using System;
class GfG {
// Function to check if such a subarray exists
static bool isSubsetSumZero(int[] arr, int k) {
int n = arr.Length;
int left = 0, right = 0, sum = 0;
// Traverse the array using a sliding window
while (right < n) {
sum += arr[right];
// Check if window size is equal to k
if (right - left + 1 == k) {
// If sum of window is 0, subarray exists
if (sum == 0) {
return true;
}
// Slide the window by removing left element
sum -= arr[left];
left++;
}
right++;
}
return false;
}
public static void Main() {
int[] arr = {1, -1, 1, -1};
int k = 2;
if (isSubsetSumZero(arr, k)) {
Console.Write("true");
} else {
Console.Write("false");
}
}
}
// JavaScript program to check if there exists
// a subarray of size k with sum 0
// using Sliding Window
// Function to check if such a subset exists
function isSubsetSumZero(arr, k) {
let n = arr.length;
let left = 0, right = 0, sum = 0;
// Traverse the array using a sliding window
while (right < n) {
sum += arr[right];
// Check if window size is equal to k
if (right - left + 1 === k) {
// If sum of window is 0, subarray exists
if (sum === 0) {
return true;
}
// Slide the window by removing left element
sum -= arr[left];
left++;
}
right++;
}
return false;
}
// Driver Code
let arr = [1, -1, 1, -1];
let k = 2;
if (isSubsetSumZero(arr, k)) {
console.log("true");
} else {
console.log("false");
}
Output
true