Sum of minimum and maximum elements of all subarrays of size k.
Last Updated :
13 Dec, 2024
Given an array of both positive and negative integers, the task is to compute sum of minimum and maximum elements of all sub-array of size k.
Examples:
Input : arr[] = {2, 5, -1, 7, -3, -1, -2}
K = 4
Output : 18
Explanation : Subarrays of size 4 are :
{2, 5, -1, 7}, min + max = -1 + 7 = 6
{5, -1, 7, -3}, min + max = -3 + 7 = 4
{-1, 7, -3, -1}, min + max = -3 + 7 = 4
{7, -3, -1, -2}, min + max = -3 + 7 = 4
Missing sub arrays -
{2, -1, 7, -3}
{2, 7, -3, -1}
{2, -3, -1, -2}
{5, 7, -3, -1}
{5, -3, -1, -2}
and few more -- why these were not considered??
Considering missing arrays result coming as 27
Sum of all min & max = 6 + 4 + 4 + 4 = 18
This problem is mainly an extension of below problem.
Maximum of all subarrays of size k
Naive Approach:
Run two loops to generate all subarrays and then choose all subarrays of size k and find maximum and minimum values. Finally, return the sum of all maximum and minimum elements.
Steps:
- Initialize a variable sum with value 0 to store the final answer
- Run two loops to find all subarrays
- Simultaneously find the length of the subarray
- If there is any subarray of size k
- Then find its maximum and minimum element
- Then add that to the sum variable
- In the last print/return value stored in the sum variable
Implementation Code:
C++
// C++ program to find sum of all minimum and maximum
// elements Of Sub-array Size k.
#include <bits/stdc++.h>
using namespace std;
// Returns sum of min and max element of all subarrays
// of size k
int SumOfKsubArray(int arr[], int N, int k)
{
// To store final answer
int sum = 0;
// Find all subarray
for (int i = 0; i < N; i++) {
// To store length of subarray
int length = 0;
for (int j = i; j < N; j++) {
// Increment the length
length++;
// When there is subarray of size k
if (length == k) {
// To store maximum and minimum element
int maxi = INT_MIN;
int mini = INT_MAX;
for (int m = i; m <= j; m++) {
// Find maximum and minimum element
maxi = max(maxi, arr[m]);
mini = min(mini, arr[m]);
}
// Add maximum and minimum element in sum
sum += maxi + mini;
}
}
}
return sum;
}
// Driver program to test above functions
int main()
{
int arr[] = { 2, 5, -1, 7, -3, -1, -2 };
int N = sizeof(arr) / sizeof(arr[0]);
int k = 4;
cout << SumOfKsubArray(arr, N, k);
return 0;
}
Java
// Java program to find sum of all minimum and maximum
// elements Of Sub-array Size k.
import java.util.Arrays;
class GFG {
// Returns sum of min and max element of all subarrays
// of size k
static int SumOfKsubArray(int[] arr, int N, int k) {
// To store the final answer
int sum = 0;
// Find all subarrays
for (int i = 0; i < N; i++) {
// To store the length of the subarray
int length = 0;
for (int j = i; j < N; j++) {
// Increment the length
length++;
// When there is a subarray of size k
if (length == k) {
// To store the maximum and minimum element
int maxi = Integer.MIN_VALUE;
int mini = Integer.MAX_VALUE;
for (int m = i; m <= j; m++) {
// Find the maximum and minimum element
maxi = Math.max(maxi, arr[m]);
mini = Math.min(mini, arr[m]);
}
// Add the maximum and minimum element to the sum
sum += maxi + mini;
}
}
}
return sum;
}
// Driver program to test above functions
public static void main(String[] args) {
int[] arr = {2, 5, -1, 7, -3, -1, -2};
int N = arr.length;
int k = 4;
System.out.println(SumOfKsubArray(arr, N, k));
}
}
//This code is contributed by Vishal Dhaygude
Python
# Returns sum of min and max element of all subarrays
# of size k
def sum_of_k_subarray(arr, N, k):
# To store final answer
sum = 0
# Find all subarrays
for i in range(N):
# To store length of subarray
length = 0
for j in range(i, N):
# Increment the length
length += 1
# When there is a subarray of size k
if length == k:
# To store maximum and minimum element
maxi = float('-inf')
mini = float('inf')
for m in range(i, j + 1):
# Find maximum and minimum element
maxi = max(maxi, arr[m])
mini = min(mini, arr[m])
# Add maximum and minimum element to sum
sum += maxi + mini
return sum
# Driver program to test above function
def main():
arr = [2, 5, -1, 7, -3, -1, -2]
N = len(arr)
k = 4
print(sum_of_k_subarray(arr, N, k))
if __name__ == "__main__":
main()
C#
using System;
class Program {
// Returns sum of min and max element of all subarrays
// of size k
static int SumOfKSubArray(int[] arr, int N, int k)
{
// To store the final answer
int sum = 0;
// Find all subarrays
for (int i = 0; i < N; i++) {
// To store the length of subarray
int length = 0;
for (int j = i; j < N; j++) {
// Increment the length
length++;
// When there is a subarray of size k
if (length == k) {
// To store the maximum and minimum
// element
int maxi = int.MinValue;
int mini = int.MaxValue;
for (int m = i; m <= j; m++) {
// Find maximum and minimum element
maxi = Math.Max(maxi, arr[m]);
mini = Math.Min(mini, arr[m]);
}
// Add maximum and minimum element in
// sum
sum += maxi + mini;
}
}
}
return sum;
}
// Driver program to test above functions
static void Main()
{
int[] arr = { 2, 5, -1, 7, -3, -1, -2 };
int N = arr.Length;
int k = 4;
Console.WriteLine(SumOfKSubArray(arr, N, k));
}
}
JavaScript
// JavaScript program to find sum of all minimum and maximum
// elements of sub-array size k.
// Returns sum of min and max element of all subarrays
// of size k
function SumOfKsubArray(arr, N, k) {
// To store final answer
let sum = 0;
// Find all subarray
for (let i = 0; i < N; i++) {
// To store length of subarray
let length = 0;
for (let j = i; j < N; j++) {
// Increment the length
length++;
// When there is subarray of size k
if (length === k) {
// To store maximum and minimum element
let maxi = Number.MIN_SAFE_INTEGER;
let mini = Number.MAX_SAFE_INTEGER;
for (let m = i; m <= j; m++) {
// Find maximum and minimum element
maxi = Math.max(maxi, arr[m]);
mini = Math.min(mini, arr[m]);
}
// Add maximum and minimum element in sum
sum += maxi + mini;
}
}
}
return sum;
}
// Driver program to test above function
const arr = [2, 5, -1, 7, -3, -1, -2];
const N = arr.length;
const k = 4;
console.log(SumOfKsubArray(arr, N, k));
Time Complexity: O(N2*k), because two loops to find all subarray and one loop to find the maximum and minimum elements in the subarray of size k
Auxiliary Space: O(1), because no extra space has been used
Method 2 (Using MultiSet):
The idea is to use Multiset data structure and sliding window concept.
- Firstly, We create a multiset of pair of {number,index}, because index would help us in removing the ith element and move to next window of size k.
- Secondly, we have i and j which are back and front pointer used to maintain a window.
- Traverse through the array and insert into multiset pair of {number,index}, and also check for windowSize, once it becomes equals to k, start your primary goal, i.e. to find sum of max & min elements.
- Then erase the ith index number from the set and move the ith pointer to next location , i.e. new window of size k.
Implementation:
C++
// C++ program to find sum of all minimum and maximum
// elements Of Sub-array Size k.
#include <bits/stdc++.h>
using namespace std;
// Returns sum of min and max element of all subarrays
// of size k
int SumOfKsubArray(int arr[], int n, int k)
{
int sum = 0; // to store our final sum
// multiset because nos. could be repeated
// multiset pair is {number,index}
multiset<pair<int, int> > ms;
int i = 0; // back pointer
int j = 0; // front pointer
while (j < n && i < n) {
ms.insert(
{ arr[j], j }); // inserting {number,index}
// front pointer - back pointer + 1 is for checking
// window size
int windowSize = j - i + 1;
// Once they become equal, start what we need to do
if (windowSize == k) {
// extracting first since set is always in
// sorted ascending order
int mini = ms.begin()->first;
// extracting last element aka beginning from
// last (numbers extraction)
int maxi = ms.rbegin()->first;
// adding summation of maximum & minimum element
// of each subarray of k into final sum
sum += (maxi + mini);
// erasing the ith index element from set as it
// won't appaer in next window of size k
ms.erase({ arr[i], i });
// increasing back pointer for next window of
// size k;
i++;
}
j++; // always increments front pointer
}
return sum;
}
// Driver program to test above functions
int main()
{
int arr[] = { 2, 5, -1, 7, -3, -1, -2 };
int n = sizeof(arr) / sizeof(arr[0]);
int k = 4;
cout << SumOfKsubArray(arr, n, k);
return 0;
}
Time Complexity: O(nlogk)
Auxiliary Space: O(k)
Method 3 (Efficient using Dequeue):
The idea is to use Dequeue data structure and sliding window concept. We create two empty double-ended queues of size k ('S' , 'G') that only store indices of elements of current window that are not useless. An element is useless if it can not be maximum or minimum of next subarrays.
Implementation:
C++
// C++ program to find sum of all minimum and maximum
// elements Of Sub-array Size k.
#include<bits/stdc++.h>
using namespace std;
// Returns sum of min and max element of all subarrays
// of size k
int SumOfKsubArray(int arr[] , int n , int k)
{
int sum = 0; // Initialize result
// The queue will store indexes of useful elements
// in every window
// In deque 'G' we maintain decreasing order of
// values from front to rear
// In deque 'S' we maintain increasing order of
// values from front to rear
deque< int > S(k), G(k);
// Process first window of size K
int i = 0;
for (i = 0; i < k; i++)
{
// Remove all previous greater elements
// that are useless.
while ( (!S.empty()) && arr[S.back()] >= arr[i])
S.pop_back(); // Remove from rear
// Remove all previous smaller that are elements
// are useless.
while ( (!G.empty()) && arr[G.back()] <= arr[i])
G.pop_back(); // Remove from rear
// Add current element at rear of both deque
G.push_back(i);
S.push_back(i);
}
// Process rest of the Array elements
for ( ; i < n; i++ )
{
// Element at the front of the deque 'G' & 'S'
// is the largest and smallest
// element of previous window respectively
sum += arr[S.front()] + arr[G.front()];
// Remove all elements which are out of this
// window
if ( !S.empty() && S.front() == i - k)
S.pop_front();
if ( !G.empty() && G.front() == i - k)
G.pop_front();
// remove all previous greater element that are
// useless
while ( (!S.empty()) && arr[S.back()] >= arr[i])
S.pop_back(); // Remove from rear
// remove all previous smaller that are elements
// are useless
while ( (!G.empty()) && arr[G.back()] <= arr[i])
G.pop_back(); // Remove from rear
// Add current element at rear of both deque
G.push_back(i);
S.push_back(i);
}
// Sum of minimum and maximum element of last window
sum += arr[S.front()] + arr[G.front()];
return sum;
}
// Driver program to test above functions
int main()
{
int arr[] = {2, 5, -1, 7, -3, -1, -2} ;
int n = sizeof(arr)/sizeof(arr[0]);
int k = 4;
cout << SumOfKsubArray(arr, n, k) ;
return 0;
}
Java
// Java program to find sum of all minimum and maximum
// elements Of Sub-array Size k.
import java.util.Deque;
import java.util.LinkedList;
public class Geeks {
// Returns sum of min and max element of all subarrays
// of size k
public static int SumOfKsubArray(int arr[] , int k)
{
int sum = 0; // Initialize result
// The queue will store indexes of useful elements
// in every window
// In deque 'G' we maintain decreasing order of
// values from front to rear
// In deque 'S' we maintain increasing order of
// values from front to rear
Deque<Integer> S=new LinkedList<>(),G=new LinkedList<>();
// Process first window of size K
int i = 0;
for (i = 0; i < k; i++)
{
// Remove all previous greater elements
// that are useless.
while ( !S.isEmpty() && arr[S.peekLast()] >= arr[i])
S.removeLast(); // Remove from rear
// Remove all previous smaller that are elements
// are useless.
while ( !G.isEmpty() && arr[G.peekLast()] <= arr[i])
G.removeLast(); // Remove from rear
// Add current element at rear of both deque
G.addLast(i);
S.addLast(i);
}
// Process rest of the Array elements
for ( ; i < arr.length; i++ )
{
// Element at the front of the deque 'G' & 'S'
// is the largest and smallest
// element of previous window respectively
sum += arr[S.peekFirst()] + arr[G.peekFirst()];
// Remove all elements which are out of this
// window
while ( !S.isEmpty() && S.peekFirst() <= i - k)
S.removeFirst();
while ( !G.isEmpty() && G.peekFirst() <= i - k)
G.removeFirst();
// remove all previous greater element that are
// useless
while ( !S.isEmpty() && arr[S.peekLast()] >= arr[i])
S.removeLast(); // Remove from rear
// remove all previous smaller that are elements
// are useless
while ( !G.isEmpty() && arr[G.peekLast()] <= arr[i])
G.removeLast(); // Remove from rear
// Add current element at rear of both deque
G.addLast(i);
S.addLast(i);
}
// Sum of minimum and maximum element of last window
sum += arr[S.peekFirst()] + arr[G.peekFirst()];
return sum;
}
public static void main(String args[])
{
int arr[] = {2, 5, -1, 7, -3, -1, -2} ;
int k = 4;
System.out.println(SumOfKsubArray(arr, k));
}
}
//This code is contributed by Gaurav Tiwari
Python
# Python3 program to find Sum of all minimum and maximum
# elements Of Sub-array Size k.
from collections import deque
# Returns Sum of min and max element of all subarrays
# of size k
def SumOfKsubArray(arr, n , k):
Sum = 0 # Initialize result
# The queue will store indexes of useful elements
# in every window
# In deque 'G' we maintain decreasing order of
# values from front to rear
# In deque 'S' we maintain increasing order of
# values from front to rear
S = deque()
G = deque()
# Process first window of size K
for i in range(k):
# Remove all previous greater elements
# that are useless.
while ( len(S) > 0 and arr[S[-1]] >= arr[i]):
S.pop() # Remove from rear
# Remove all previous smaller that are elements
# are useless.
while ( len(G) > 0 and arr[G[-1]] <= arr[i]):
G.pop() # Remove from rear
# Add current element at rear of both deque
G.append(i)
S.append(i)
# Process rest of the Array elements
for i in range(k, n):
# Element at the front of the deque 'G' & 'S'
# is the largest and smallest
# element of previous window respectively
Sum += arr[S[0]] + arr[G[0]]
# Remove all elements which are out of this
# window
while ( len(S) > 0 and S[0] <= i - k):
S.popleft()
while ( len(G) > 0 and G[0] <= i - k):
G.popleft()
# remove all previous greater element that are
# useless
while ( len(S) > 0 and arr[S[-1]] >= arr[i]):
S.pop() # Remove from rear
# remove all previous smaller that are elements
# are useless
while ( len(G) > 0 and arr[G[-1]] <= arr[i]):
G.pop() # Remove from rear
# Add current element at rear of both deque
G.append(i)
S.append(i)
# Sum of minimum and maximum element of last window
Sum += arr[S[0]] + arr[G[0]]
return Sum
# Driver program to test above functions
arr=[2, 5, -1, 7, -3, -1, -2]
n = len(arr)
k = 4
print(SumOfKsubArray(arr, n, k))
# This code is contributed by mohit kumar
C#
// C# program to find sum of all minimum and maximum
// elements Of Sub-array Size k.
using System;
using System.Collections.Generic;
class Geeks
{
// Returns sum of min and max element of all subarrays
// of size k
public static int SumOfKsubArray(int []arr , int k)
{
int sum = 0; // Initialize result
// The queue will store indexes of useful elements
// in every window
// In deque 'G' we maintain decreasing order of
// values from front to rear
// In deque 'S' we maintain increasing order of
// values from front to rear
List<int> S = new List<int>();
List<int> G = new List<int>();
// Process first window of size K
int i = 0;
for (i = 0; i < k; i++)
{
// Remove all previous greater elements
// that are useless.
while ( S.Count != 0 && arr[S[S.Count - 1]] >= arr[i])
S.RemoveAt(S.Count - 1); // Remove from rear
// Remove all previous smaller that are elements
// are useless.
while ( G.Count != 0 && arr[G[G.Count - 1]] <= arr[i])
G.RemoveAt(G.Count - 1); // Remove from rear
// Add current element at rear of both deque
G.Add(i);
S.Add(i);
}
// Process rest of the Array elements
for ( ; i < arr.Length; i++ )
{
// Element at the front of the deque 'G' & 'S'
// is the largest and smallest
// element of previous window respectively
sum += arr[S[0]] + arr[G[0]];
// Remove all elements which are out of this
// window
while ( S.Count != 0 && S[0] <= i - k)
S.RemoveAt(0);
while ( G.Count != 0 && G[0] <= i - k)
G.RemoveAt(0);
// remove all previous greater element that are
// useless
while ( S.Count != 0 && arr[S[S.Count-1]] >= arr[i])
S.RemoveAt(S.Count - 1 ); // Remove from rear
// remove all previous smaller that are elements
// are useless
while ( G.Count != 0 && arr[G[G.Count - 1]] <= arr[i])
G.RemoveAt(G.Count - 1); // Remove from rear
// Add current element at rear of both deque
G.Add(i);
S.Add(i);
}
// Sum of minimum and maximum element of last window
sum += arr[S[0]] + arr[G[0]];
return sum;
}
// Driver code
public static void Main(String []args)
{
int []arr = {2, 5, -1, 7, -3, -1, -2} ;
int k = 4;
Console.WriteLine(SumOfKsubArray(arr, k));
}
}
// This code is contributed by gauravrajput1
JavaScript
// JavaScript program to find sum of all minimum and maximum
// elements Of Sub-array Size k.
// Returns sum of min and max element of all subarrays
// of size k
function SumOfKsubArray(arr , k)
{
let sum = 0; // Initialize result
// The queue will store indexes of useful elements
// in every window
// In deque 'G' we maintain decreasing order of
// values from front to rear
// In deque 'S' we maintain increasing order of
// values from front to rear
let S = [];
let G = [];
// Process first window of size K
let i = 0;
for (i = 0; i < k; i++)
{
// Remove all previous greater elements
// that are useless.
while ( S.length != 0 && arr[S[S.length - 1]] >= arr[i])
S.pop(); // Remove from rear
// Remove all previous smaller that are elements
// are useless.
while ( G.length != 0 && arr[G[G.length - 1]] <= arr[i])
G.pop(); // Remove from rear
// Add current element at rear of both deque
G.push(i);
S.push(i);
}
// Process rest of the Array elements
for ( ; i < arr.length; i++ )
{
// Element at the front of the deque 'G' & 'S'
// is the largest and smallest
// element of previous window respectively
sum += arr[S[0]] + arr[G[0]];
// Remove all elements which are out of this
// window
while ( S.length != 0 && S[0] <= i - k)
S.shift(0);
while ( G.length != 0 && G[0] <= i - k)
G.shift(0);
// remove all previous greater element that are
// useless
while ( S.length != 0 && arr[S[S.length-1]] >= arr[i])
S.pop(); // Remove from rear
// remove all previous smaller that are elements
// are useless
while ( G.length != 0 && arr[G[G.length - 1]] <= arr[i])
G.pop(); // Remove from rear
// Add current element at rear of both deque
G.push(i);
S.push(i);
}
// Sum of minimum and maximum element of last window
sum += arr[S[0]] + arr[G[0]];
return sum;
}
// Driver code
let arr = [2, 5, -1, 7, -3, -1, -2];
let k = 4;
console.log(SumOfKsubArray(arr, k));
// This code is contributed by _saurabh_jaiswal
Time Complexity: O(n)
Auxiliary Space: O(k)
Similar Reads
Basics & Prerequisites
Data Structures
Array Data StructureIn this article, we introduce array, implementation in different popular languages, its basic operations and commonly seen problems / interview questions. An array stores items (in case of C/C++ and Java Primitive Arrays) or their references (in case of Python, JS, Java Non-Primitive) at contiguous
3 min read
String in Data StructureA string is a sequence of characters. The following facts make string an interesting data structure.Small set of elements. Unlike normal array, strings typically have smaller set of items. For example, lowercase English alphabet has only 26 characters. ASCII has only 256 characters.Strings are immut
2 min read
Hashing in Data StructureHashing is a technique used in data structures that efficiently stores and retrieves data in a way that allows for quick access. Hashing involves mapping data to a specific index in a hash table (an array of items) using a hash function. It enables fast retrieval of information based on its key. The
2 min read
Linked List Data StructureA linked list is a fundamental data structure in computer science. It mainly allows efficient insertion and deletion operations compared to arrays. Like arrays, it is also used to implement other data structures like stack, queue and deque. Hereâs the comparison of Linked List vs Arrays Linked List:
2 min read
Stack Data StructureA Stack is a linear data structure that follows a particular order in which the operations are performed. The order may be LIFO(Last In First Out) or FILO(First In Last Out). LIFO implies that the element that is inserted last, comes out first and FILO implies that the element that is inserted first
2 min read
Queue Data StructureA Queue Data Structure is a fundamental concept in computer science used for storing and managing data in a specific order. It follows the principle of "First in, First out" (FIFO), where the first element added to the queue is the first one to be removed. It is used as a buffer in computer systems
2 min read
Tree Data StructureTree Data Structure is a non-linear data structure in which a collection of elements known as nodes are connected to each other via edges such that there exists exactly one path between any two nodes. Types of TreeBinary Tree : Every node has at most two childrenTernary Tree : Every node has at most
4 min read
Graph Data StructureGraph Data Structure is a collection of nodes connected by edges. It's used to represent relationships between different entities. If you are looking for topic-wise list of problems on different topics like DFS, BFS, Topological Sort, Shortest Path, etc., please refer to Graph Algorithms. Basics of
3 min read
Trie Data StructureThe Trie data structure is a tree-like structure used for storing a dynamic set of strings. It allows for efficient retrieval and storage of keys, making it highly effective in handling large datasets. Trie supports operations such as insertion, search, deletion of keys, and prefix searches. In this
15+ min read
Algorithms
Searching AlgorithmsSearching algorithms are essential tools in computer science used to locate specific items within a collection of data. In this tutorial, we are mainly going to focus upon searching in an array. When we search an item in an array, there are two most common algorithms used based on the type of input
2 min read
Sorting AlgorithmsA Sorting Algorithm is used to rearrange a given array or list of elements in an order. For example, a given array [10, 20, 5, 2] becomes [2, 5, 10, 20] after sorting in increasing order and becomes [20, 10, 5, 2] after sorting in decreasing order. There exist different sorting algorithms for differ
3 min read
Introduction to RecursionThe process in which a function calls itself directly or indirectly is called recursion and the corresponding function is called a recursive function. A recursive algorithm takes one step toward solution and then recursively call itself to further move. The algorithm stops once we reach the solution
14 min read
Greedy AlgorithmsGreedy algorithms are a class of algorithms that make locally optimal choices at each step with the hope of finding a global optimum solution. At every step of the algorithm, we make a choice that looks the best at the moment. To make the choice, we sometimes sort the array so that we can always get
3 min read
Graph AlgorithmsGraph is a non-linear data structure like tree data structure. The limitation of tree is, it can only represent hierarchical data. For situations where nodes or vertices are randomly connected with each other other, we use Graph. Example situations where we use graph data structure are, a social net
3 min read
Dynamic Programming or DPDynamic Programming is an algorithmic technique with the following properties.It is mainly an optimization over plain recursion. Wherever we see a recursive solution that has repeated calls for the same inputs, we can optimize it using Dynamic Programming. The idea is to simply store the results of
3 min read
Bitwise AlgorithmsBitwise algorithms in Data Structures and Algorithms (DSA) involve manipulating individual bits of binary representations of numbers to perform operations efficiently. These algorithms utilize bitwise operators like AND, OR, XOR, NOT, Left Shift, and Right Shift.BasicsIntroduction to Bitwise Algorit
4 min read
Advanced
Segment TreeSegment Tree is a data structure that allows efficient querying and updating of intervals or segments of an array. It is particularly useful for problems involving range queries, such as finding the sum, minimum, maximum, or any other operation over a specific range of elements in an array. The tree
3 min read
Pattern SearchingPattern searching algorithms are essential tools in computer science and data processing. These algorithms are designed to efficiently find a particular pattern within a larger set of data. Patten SearchingImportant Pattern Searching Algorithms:Naive String Matching : A Simple Algorithm that works i
2 min read
GeometryGeometry is a branch of mathematics that studies the properties, measurements, and relationships of points, lines, angles, surfaces, and solids. From basic lines and angles to complex structures, it helps us understand the world around us.Geometry for Students and BeginnersThis section covers key br
2 min read
Interview Preparation
Practice Problem