Given an array a[] of size n and an integer k, the task is to find the total number of cuts that you can make such that for each cut these two conditions are satisfied:
- Sum of the largest element in the left part and the smallest element in the right part is greater than or equal to k.
- A cut divides an array into two parts. It may divide into equal or unequal lengths (non-zero).
Examples:
Input: k = 3, a[] = {1, 2, 3}
Output: 2
Explanation: Two ways in which array is divided to satisfy above conditions are: {1} and {2, 3} -> 1+2 = 3(satisfies the condition) and {1, 2} and {3} -> 2+3 = 5(satisfies the condition)Input: k = 5, a[] = {1, 2, 3, 4, 5}
Output: 3
Explanation: {1, 2} and {3, 4, 5} -> 2+3 = 5, {1, 2, 3} and {4, 5} -> 3+4 = 7, {1, 2, 3, 4} and {5} -> 4+5 = 9
Table of Content
[Naive Approach] Using Nested Traversal ā O(n²) Time and O(1) Space
The idea is to try every possible cut position in the array. For each cut, we separately find the maximum element in the left subarray and the minimum element in the right subarray. If the sum of these two values is at least
k, then that cut is considered valid.
- Iterate through all possible cut positions in the array
- For each cut, find the maximum element in the left part
- Find the minimum element in the right part
- If
maxLeft + minRight >= k, increase the count
#include <bits/stdc++.h>
using namespace std;
// Function to find the total
// number of possible cuts
int totalCuts(vector<int> &a, int k)
{
int n = a.size();
int count = 0;
// Try every possible cut
for (int i = 0; i < n - 1; i++) {
int maxi = INT_MIN;
int mini = INT_MAX;
// Find maximum in left part
for (int j = 0; j <= i; j++) {
maxi = max(maxi, a[j]);
}
// Find minimum in right part
for (int j = i + 1; j < n; j++) {
mini = min(mini, a[j]);
}
// Check valid cut condition
if (maxi + mini >= k)
count++;
}
return count;
}
// Driver code
int main()
{
int k = 3;
vector<int> arr = {1, 2, 3};
// Function call
int result = totalCuts(arr, k);
cout << result << endl;
return 0;
}
// Java program to find total number of possible cuts
import java.util.*;
class GfG {
// Function to find the total number of possible cuts
static int totalCuts(int[] a, int k) {
int n = a.length;
int count = 0;
// Try every possible cut
for (int i = 0; i < n - 1; i++) {
int maxi = Integer.MIN_VALUE;
int mini = Integer.MAX_VALUE;
// Find maximum in left part
for (int j = 0; j <= i; j++) {
maxi = Math.max(maxi, a[j]);
}
// Find minimum in right part
for (int j = i + 1; j < n; j++) {
mini = Math.min(mini, a[j]);
}
// Check valid cut condition
if (maxi + mini >= k)
count++;
}
return count;
}
// Driver code
public static void main(String[] args) {
int k = 3;
int[] arr = {1, 2, 3};
// Function call
int result = totalCuts(arr, k);
System.out.println(result);
}
}
# Python program to find total number of possible cuts
# Function to find the total number of possible cuts
def totalCuts(a, k):
n = len(a)
count = 0
# Try every possible cut
for i in range(n - 1):
maxi = float('-inf')
mini = float('inf')
# Find maximum in left part
for j in range(i + 1):
maxi = max(maxi, a[j])
# Find minimum in right part
for j in range(i + 1, n):
mini = min(mini, a[j])
# Check valid cut condition
if maxi + mini >= k:
count += 1
return count
# Driver code
if __name__ == "__main__":
k = 3
arr = [1, 2, 3]
# Function call
result = totalCuts(arr, k)
print(result)
// C# program to find total number of possible cuts
using System;
class GfG {
// Function to find the total number of possible cuts
static int totalCuts(int[] a, int k) {
int n = a.Length;
int count = 0;
// Try every possible cut
for (int i = 0; i < n - 1; i++) {
int maxi = int.MinValue;
int mini = int.MaxValue;
// Find maximum in left part
for (int j = 0; j <= i; j++) {
maxi = Math.Max(maxi, a[j]);
}
// Find minimum in right part
for (int j = i + 1; j < n; j++) {
mini = Math.Min(mini, a[j]);
}
// Check valid cut condition
if (maxi + mini >= k)
count++;
}
return count;
}
// Driver code
static void Main(string[] args) {
int k = 3;
int[] arr = {1, 2, 3};
// Function call
int result = totalCuts(arr, k);
Console.WriteLine(result);
}
}
// JavaScript program to find total number of possible cuts
// Function to find the total number of possible cuts
function totalCuts(a, k) {
let n = a.length;
let count = 0;
// Try every possible cut
for (let i = 0; i < n - 1; i++) {
let maxi = -Infinity;
let mini = Infinity;
// Find maximum in left part
for (let j = 0; j <= i; j++) {
maxi = Math.max(maxi, a[j]);
}
// Find minimum in right part
for (let j = i + 1; j < n; j++) {
mini = Math.min(mini, a[j]);
}
// Check valid cut condition
if (maxi + mini >= k)
count++;
}
return count;
}
// Driver code
const k = 3;
const arr = [1, 2, 3];
// Function call
const result = totalCuts(arr, k);
console.log(result);
[Efficient Approach] Using Prefix Maximum + Suffix Minimum ā O(n) Time and O(n) Space
For a cut after index
i, we need the maximum value on the left side and the minimum value on the right side.If their sum is at least
k, the cut is valid.We preprocess the minimum values from the right side using a suffix array and maintain the running maximum from the left while traversing.
- Build a suffix minimum array storing minimum element from index
ito end - Traverse the array while maintaining the maximum element seen so far on the left
- For each cut position, check if
leftMax + rightMin >= k - Count all valid cuts and return the total
#include <bits/stdc++.h>
using namespace std;
// Function to find the total
// number of possible cuts
int totalCuts(vector<int> &arr, int k)
{
int n = arr.size();
int maxi = -1;
int count = 0;
vector<int> minRight(n);
minRight[n - 1] = arr[n - 1];
// Loop to store the minimum from
// right end till i
for (int i = n - 2; i >= 0; i--) {
if (arr[i] < minRight[i + 1])
minRight[i] = arr[i];
else
minRight[i] = minRight[i + 1];
}
// Loop to find the number of
// possible cuts
for (int i = 0; i < n - 1; i++) {
maxi = maxi > arr[i] ? maxi : arr[i];
if (maxi + minRight[i + 1] >= k)
count++;
}
return count;
}
// Driver code
int main()
{
int k = 3;
vector<int> arr = {1, 2, 3};
// Function call
int result = totalCuts(arr, k);
cout << result << endl;
return 0;
}
// Java program to find total number of possible cuts (Optimized)
import java.util.*;
class GfG {
// Function to find the total number of possible cuts
static int totalCuts(ArrayList<Integer> arr, int k) {
int n = arr.size();
int maxi = -1;
int count = 0;
int[] minRight = new int[n];
minRight[n - 1] = arr.get(n - 1);
// Loop to store the minimum from right end till i
for (int i = n - 2; i >= 0; i--) {
if (arr.get(i) < minRight[i + 1])
minRight[i] = arr.get(i);
else
minRight[i] = minRight[i + 1];
}
// Loop to find the number of possible cuts
for (int i = 0; i < n - 1; i++) {
maxi = maxi > arr.get(i) ? maxi : arr.get(i);
if (maxi + minRight[i + 1] >= k)
count++;
}
return count;
}
// Driver code
public static void main(String[] args) {
int k = 3;
ArrayList<Integer> arr = new ArrayList<>();
arr.add(1);
arr.add(2);
arr.add(3);
// Function call
int result = totalCuts(arr, k);
System.out.println(result);
}
}
# Python program to find total number of possible cuts (Optimized)
# Function to find the total number of possible cuts
def totalCuts(arr, k):
n = len(arr)
maxi = -1
count = 0
minRight = [0] * n
minRight[n - 1] = arr[n - 1]
# Loop to store the minimum from right end till i
for i in range(n - 2, -1, -1):
if arr[i] < minRight[i + 1]:
minRight[i] = arr[i]
else:
minRight[i] = minRight[i + 1]
# Loop to find the number of possible cuts
for i in range(n - 1):
maxi = maxi if maxi > arr[i] else arr[i]
if maxi + minRight[i + 1] >= k:
count += 1
return count
# Driver code
if __name__ == "__main__":
k = 3
arr = [1, 2, 3]
# Function call
result = totalCuts(arr, k)
print(result)
// C# program to find total number of possible cuts (Optimized)
using System;
class GfG {
// Function to find the total number of possible cuts
static int totalCuts(int[] arr, int k) {
int n = arr.Length;
int maxi = -1;
int count = 0;
int[] minRight = new int[n];
minRight[n - 1] = arr[n - 1];
// Loop to store the minimum from right end till i
for (int i = n - 2; i >= 0; i--) {
if (arr[i] < minRight[i + 1])
minRight[i] = arr[i];
else
minRight[i] = minRight[i + 1];
}
// Loop to find the number of possible cuts
for (int i = 0; i < n - 1; i++) {
maxi = maxi > arr[i] ? maxi : arr[i];
if (maxi + minRight[i + 1] >= k)
count++;
}
return count;
}
// Driver code
static void Main(string[] args) {
int k = 3;
int[] arr = {1, 2, 3};
// Function call
int result = totalCuts(arr, k);
Console.WriteLine(result);
}
}
// JavaScript program to find total number of possible cuts (Optimized)
// Function to find the total number of possible cuts
function totalCuts(arr, k) {
let n = arr.length;
let maxi = -1;
let count = 0;
let minRight = new Array(n);
minRight[n - 1] = arr[n - 1];
// Loop to store the minimum from right end till i
for (let i = n - 2; i >= 0; i--) {
if (arr[i] < minRight[i + 1])
minRight[i] = arr[i];
else
minRight[i] = minRight[i + 1];
}
// Loop to find the number of possible cuts
for (let i = 0; i < n - 1; i++) {
maxi = maxi > arr[i] ? maxi : arr[i];
if (maxi + minRight[i + 1] >= k)
count++;
}
return count;
}
// Driver code
const k = 3;
const arr = [1, 2, 3];
// Function call
const result = totalCuts(arr, k);
console.log(result);
Output
2