Split the array into N subarrays where each subarray has size 1 or sum at least K
Last Updated :
10 Feb, 2024
Given an array arr[] of size N and integer K. Task for this problem is to check if given array can be split into N continuous subarrays by performing given operations. In one operation choose existing array which may be result of previous operation and split it into two subarrays with each of subarray follows at least one of the following properties:
- The size of subarray is 1.
- The sum of elements of that subarray is at least K.
Examples:
Input: arr[] = {2, 3, 3, 2, 3}, K = 6
Output: 1
Explanation:
- In first operation partition {2, 3, 3, 2, 3} into {2, 3, 3, 2} + {3} each partitioned subarray satisfies required property. Subarrays are {{2, 3, 3, 2} + {3}}
- In second operation partition {2, 3, 3, 2} into {2, 3, 3} + {2} each partitioned subarray satisfies required property. Subarrays are {{2, 3, 3} + {2} + {3}}
- In third operation partition {2, 3, 3} into {2} + {3, 3} each partitioned subarray satisfies required property. Subarrays are {{2} + {3, 3} + {2} + {3}}
- In fourth operation partition {3, 3} into {3} + {3} each partitioned subarray satisfies required property. Subarrays are {{2} + {3} + {3} + {2} + {3}}
so, it is possible to split given subarray into N subarrays.
Input: arr[] = {2, 1, 3}, K = 5
Output: 0
Explanation: Array arr[] cannot be partitioned into N = 3 subarrays by performing any operation
Approach: Implement the idea below to solve the problem:
Dynamic Programming can be used to solve this problem. The main concept of DP in the problem will be:
DP[i][j] will store whether it is possible to partition subarray from i to j (arr[i], arr[i + 1]......, arr[j])
Transition:
dp[i][j] = (dp[i][j] | dp[i][k] & dp[k + 1][j]) (splitting array for each k from i to j - 1)
Bitwise AND operation is used so when both arrays dp[i][k] and dp[k + 1][j] satisfies required property then only dp[i][j] will be 1. Also, to make sure while partitioning either one of above conditions is being satisfied by partitioned subarrays.
To check if partitioned subarray has sum at least K prefix sum array will be used.
Step-by-step algorithm:
- Declare prefix array pre[N + 1] such that pre[i] stores the prefix sum till ith element.
- Declare dp[N + 1][N + 1] and for every i from 0 to N update dp[i][i] as 1
- To calculate answer for smaller subarrays, iterate from 1 to N as size and check for all values of i and j:
- dp[i][j] = (dp[i][j] | dp[i][k] & dp[k + 1][j]) (splitting array for each k from i to j - 1)
- Return dp[1][N] (which is answer whether array arr[] can be partitioned in N subarrays)
Below is the implementation of the above approach:
C++
// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
// Function to Check if array can be partitioned in N
// subarrays such that after each operation every partition
// have sum at least K or size 1
int isPartitionPossible(int arr[], int N, int K)
{
// prefix sum array
vector<int> pre(N + 1, 0);
// filling prefix sum array
for (int i = 1; i <= N; i++)
pre[i] = arr[i - 1];
// taking prefix sum
for (int i = 1; i <= N; i++) {
pre[i] = pre[i] + pre[i - 1];
}
// DP array initalized with 0
vector<vector<int> > dp(N + 1, vector<int>(N + 1, 0));
// Base Case
for (int i = 0; i <= N; i++)
dp[i][i] = 1;
// iterating on each size of subarray
for (int size = 1; size <= N; size++) {
// iterating for start i
for (int i = 1; i <= N - size + 1; i++) {
// finding answer for array arr[i:j]
int j = i + size - 1;
// partitioning string at position k
for (int k = i; k < j; k++) {
// either one of the required property
// should be true for paritioned subarrays
if ((k - i == 0 or pre[k] - pre[i - 1] >= K)
and (j - k - 1 == 0
or pre[j] - pre[k] >= K))
// update dp table according to
// transitions
dp[i][j]
= (dp[i][j]
| (dp[i][k] & dp[k + 1][j]));
}
}
}
// returning final answer whether it is possible to
// parition given array in N subarrays
return dp[1][N];
}
// Driver Code
int main()
{
// Input
int N = 5, K = 6;
int arr[] = { 2, 3, 3, 2, 3 };
// Function Call
cout << isPartitionPossible(arr, N, K) << endl;
return 0;
}
Java
public class Main {
// Function to check if partition is possible
static boolean isPartitionPossible(int[] arr, int N,
int K)
{
// Prefix sum array
int[] pre = new int[N + 1];
// Filling prefix sum array
for (int i = 1; i <= N; i++) {
pre[i] = arr[i - 1];
}
// Taking prefix sum
for (int i = 1; i <= N; i++) {
pre[i] = pre[i] + pre[i - 1];
}
// DP array initialized with 0
boolean[][] dp = new boolean[N + 1][N + 1];
// Base Case
for (int i = 0; i <= N; i++) {
dp[i][i] = true;
}
// Iterating on each size of subarray
for (int size = 1; size <= N; size++) {
// Iterating for start i
for (int i = 1; i <= N - size + 1; i++) {
// Finding answer for array arr[i:j]
int j = i + size - 1;
// Partitioning string at position k
for (int k = i; k < j; k++) {
// Either one of the required property
// should be true for partitioned
// subarrays
if ((k - i == 0
|| pre[k] - pre[i - 1] >= K)
&& (j - k - 1 == 0
|| pre[j] - pre[k] >= K)) {
// Update dp table according to
// transitions
dp[i][j]
= dp[i][j]
|| (dp[i][k] && dp[k + 1][j]);
}
}
}
}
// Returning final answer whether it is possible to
// partition the given array into N subarrays
return dp[1][N];
}
// Driver Code
public static void main(String[] args)
{
// Input
int N = 5;
int K = 6;
int[] arr = { 2, 3, 3, 2, 3 };
// Function Call
System.out.println(isPartitionPossible(arr, N, K));
}
}
Python3
def is_partition_possible(arr, N, K):
# prefix sum array
pre = [0] * (N + 1)
# filling prefix sum array
for i in range(1, N + 1):
pre[i] = arr[i - 1]
# taking prefix sum
for i in range(1, N + 1):
pre[i] = pre[i] + pre[i - 1]
# DP array initialized with 0
dp = [[0] * (N + 1) for _ in range(N + 1)]
# Base Case
for i in range(N + 1):
dp[i][i] = 1
# iterating on each size of subarray
for size in range(1, N + 1):
# iterating for start i
for i in range(1, N - size + 2):
# finding answer for array arr[i:j]
j = i + size - 1
# partitioning string at position k
for k in range(i, j):
# either one of the required property
# should be true for partitioned subarrays
if ((k - i == 0 or pre[k] - pre[i - 1] >= K) and
(j - k - 1 == 0 or pre[j] - pre[k] >= K)):
# update dp table according to transitions
dp[i][j] = dp[i][j] | (dp[i][k] & dp[k + 1][j])
# returning final answer whether it is possible to
# partition given array into N subarrays
return dp[1][N]
# Driver Code
if __name__ == "__main__":
# Input
N = 5
K = 6
arr = [2, 3, 3, 2, 3]
# Function Call
print(is_partition_possible(arr, N, K))
C#
using System;
class GFG
{
// Function to check if array can be partitioned in N
// subarrays such that after each operation every partition
// has sum at least K or size 1
static int IsPartitionPossible(int[] arr, int N, int K)
{
// Prefix sum array
int[] pre = new int[N + 1];
// Filling prefix sum array
for (int i = 1; i <= N; i++)
pre[i] = arr[i - 1];
// Taking prefix sum
for (int i = 1; i <= N; i++)
pre[i] = pre[i] + pre[i - 1];
// DP array initialized with 0
int[,] dp = new int[N + 1, N + 1];
// Base Case
for (int i = 0; i <= N; i++)
dp[i, i] = 1;
// Iterating on each size of subarray
for (int size = 1; size <= N; size++)
{
// Iterating for start i
for (int i = 1; i <= N - size + 1; i++)
{
// Finding answer for array arr[i:j]
int j = i + size - 1;
// Partitioning string at position k
for (int k = i; k < j; k++)
{
// Either one of the required property
// should be true for partitioned subarrays
if ((k - i == 0 || pre[k] - pre[i - 1] >= K)
&& (j - k - 1 == 0 || pre[j] - pre[k] >= K))
{
// Update dp table according to transitions
dp[i, j] = (dp[i, j] | (dp[i, k] & dp[k + 1, j]));
}
}
}
}
// Returning final answer whether it is possible to
// partition the given array in N subarrays
return dp[1, N];
}
// Driver Code
static void Main()
{
// Input
int N = 5, K = 6;
int[] arr = { 2, 3, 3, 2, 3 };
// Function Call
Console.WriteLine(IsPartitionPossible(arr, N, K));
}
}
JavaScript
<script>
function isPartitionPossible(arr, N, K) {
// Prefix sum array with an additional initial 0 for ease of calculation
let pre = new Array(N + 1).fill(0);
// Filling prefix sum array
for (let i = 1; i <= N; i++) {
pre[i] = arr[i - 1];
}
// Taking prefix sum
for (let i = 1; i <= N; i++) {
pre[i] = pre[i] + pre[i - 1];
}
// DP array initialized with false
let dp = Array.from({ length: N + 1 }, () => Array(N + 1).fill(false));
// Base Case
for (let i = 0; i <= N; i++) {
dp[i][i] = true;
}
// Iterating on each size of subarray
for (let size = 1; size <= N; size++) {
// Iterating for start i
for (let i = 1; i <= N - size + 1; i++) {
// Finding answer for array arr[i:j]
let j = i + size - 1;
// Partitioning string at position k
for (let k = i; k < j; k++) {
// Either one of the required property should be true for partitioned subarrays
if ((k - i == 0 || pre[k] - pre[i - 1] >= K) && (j - k - 1 == 0 || pre[j] - pre[k] >= K)) {
// Update dp table according to transitions
dp[i][j] = dp[i][j] || (dp[i][k] && dp[k + 1][j]);
}
}
}
}
// Returning final answer whether it is possible to partition the given array into subarrays
return dp[1][N];
}
// Driver Code
let N = 5;
let K = 6;
let arr = [2, 3, 3, 2, 3];
// Function Call
console.log(isPartitionPossible(arr, N, K));
</script>
Time Complexity: O(N3), where N is the size of input array arr[].
Auxiliary Space: O(N2)
Similar Reads
Split array into K disjoint subarrays such that sum of each subarray is odd. Given an array arr[] containing N elements, the task is to divide the array into K(1 ? K ? N) subarrays and such that the sum of elements of each subarray is odd. Print the starting index (1 based indexing) of each subarray after dividing the array and -1 if no such subarray exists.Note: For all sub
8 min read
First subarray having sum at least half the maximum sum of any subarray of size K Given an array arr[] and an integer K, the task is to find the first subarray which has a sum greater than or equal to half of the maximum possible sum from any subarray of size K. Examples: Input: arr[] = {2, 4, 5, 1, 4, 6, 6, 2, 1, 0}, K = 3 Output: 6 2 1 Explanation: The given array has a maximum
9 min read
Split into K subarrays to minimize the maximum sum of all subarrays Given an array arr[] and a number k, split the given array into k subarrays such that the maximum subarray sum achievable out of k subarrays formed is the minimum possible. The task is to find that possible subarray sum.Examples:Input: arr[] = [1, 2, 3, 4], k = 3 Output: 4 Explanation: Optimal Split
11 min read
Count subarrays having sum modulo K same as the length of the subarray Given an integer K and an array arr[] consisting of N positive integers, the task is to find the number of subarrays whose sum modulo K is equal to the size of the subarray. Examples: Input: arr[] = {1, 4, 3, 2}, K = 3Output: 4Explanation: 1 % 3 = 1 (1 + 4) % 3 = 2 4 % 3 = 1 (3 + 2) % 3 = 2 Therefor
15 min read
Check if itâs possible to split the Array into strictly increasing subsets of size at least K Given an array arr[] of size N and an integer K, the task is to check whether it's possible to split the array into strictly increasing subsets of size at least K. If it is possible then print "Yes". Otherwise, print "No". Examples: Input: arr[] = {5, 6, 4, 9, 12}, K = 2Output: YesExplanation: One p
6 min read
Split array into maximum subarrays such that every distinct element lies in a single subarray Given an array, arr[] of size N, the task is to split the array into the maximum number of subarrays such that the first and the last occurrence of all distinct array element lies in a single subarray. Examples: Input: arr[] = {1, 1, 2, 2}Output: 2Explanation:Split the array into subarrays {1, 1} an
6 min read
Maximize the subarray sum by choosing M subarrays of size K Given an array arr containing N positive integers, and two integers K and M, the task is to calculate the maximum sum of M subarrays of size K. Example: Input: arr[] = {1, 2, 1, 2, 6, 7, 5, 1}, M = 3, K = 2Output: 33Explanation: The three chosen subarrays are [2, 6], [6, 7] and [7, 5] respectively.
6 min read
Maximum subarray size having all subarrays sums less than k Given an array of positive integers arr[] of size n, and an integer k. The task is to find the maximum subarray size such that all subarrays of that size have sum less than or equals to k.Examples : Input : arr[] = [1, 2, 3, 4], k = 8.Output : 2Explanation: Following are the sum of subarray of size
15+ min read
Count ways to split an array into subarrays such that sum of the i-th subarray is divisible by i Given an array arr[] consisting of N integers, the task is to find the number of ways to split the array into non-empty subarrays such that the sum of the ith subarray is divisible by i. Examples: Input: arr[] = {1, 2, 3, 4}Output: 3Explanation:Following are the number of ways to split the array int
8 min read
Split array into K subarrays such that sum of maximum of all subarrays is maximized Given an array arr[] of size N and a number K, the task is to partition the given array into K contiguous subarrays such that the sum of the maximum of each subarray is the maximum possible. If it is possible to split the array in such a manner, then print the maximum possible sum. Otherwise, print
10 min read