Count of distinct differences between two maximum elements of every Subarray
Last Updated :
23 Nov, 2022
Given an array arr[] of size N. The task is to count the number of unique differences between the two maximum elements of every subarray of size at least 2 of the given array.
Examples:
Input: arr[] = { 5, 1, 3 }, N = 3
Output: 2
Explanation: The subarrays are {5, 1}, {5, 1, 3}, {1, 3}.
{5, 1} – First max = 5; Second max = 1; difference = (5 – 1) = 4
{5, 1, 3} – First max = 5; Second max = 3; difference = (5 – 3) = 2
{1, 3} – First max = 3; Second max = 1; difference = (3 – 1) = 2
Unique height differences are {4, 2} = 2
Input: arr[] = {5, 2, 3, 8}, N = 4
Output: 4
Explanation: The subarrays are: {5, 2}, {5, 2, 3}, {5, 2, 3, 8}, {2, 3}, {2, 3, 8}, {3, 8}
{5, 2} – First max = 5; Second max = 2; difference = (5 – 2) = 3
{5, 2, 3} – First max = 5; Second max = 3; difference = (5 – 3) = 2
{5, 2, 3, 8} – First max = 8; Second max = 5; difference = (8 – 5) = 3
{2, 3} – First max = 3; Second max = 2; difference = (3 – 2) = 1
{2, 3, 8} – First max = 8; Second max = 3; difference = (8 – 3) = 5
{3,8} – First max = 8; Second max = 3; difference = (8 – 3) = 5
Unique height differences are {3, 2, 1, 5} = 4
Naive Approach: The easiest way is to generate all subarrays while keeping a track of first and second maximum. Push all differences in a set to get the count of distinct values.
Follow the given steps to solve the problem:
1. Traverse from 0 to n-1 (say i).
2. Traverse from i+1 to n in a nested loop (say j).
3. If firstMax<arr[j], update secondMax with firstMax and firstMax with arr[j].
4. If secondMax<arr[j], update secondMax=arr[j].
5. Insert all values of firstMax-secondMax in a set.
6. Return the size of the set as the final answer.
C++14
#include <bits/stdc++.h>
using namespace std;
int DistinctR( int * arr, int & n)
{
unordered_set< int >dist;
int firstMax,secondMax;
for ( int i=0;i<n-1;i++)
{
firstMax=arr[i];
secondMax=INT_MIN;
for ( int j=i+1;j<n;j++){
if (firstMax<arr[j])
{
secondMax=firstMax;
firstMax=arr[j];
}
else if (secondMax<arr[j])
secondMax=arr[j];
dist.insert(firstMax-secondMax);
}
}
return dist.size();
}
int main()
{
int arr[]={5,1,3};
int n= sizeof (arr)/ sizeof (arr[0]);
cout<<DistinctR(arr,n);
return 0;
}
|
Java
import java.util.HashSet;
class GFG
{
static int DistinctR( int [] arr, int n)
{
HashSet<Integer> dist = new HashSet<Integer>();
int firstMax, secondMax;
for ( int i = 0 ; i < n - 1 ; i++)
{
firstMax = arr[i];
secondMax = Integer.MIN_VALUE;
for ( int j = i + 1 ; j < n; j++){
if (firstMax < arr[j])
{
secondMax = firstMax;
firstMax = arr[j];
}
else if (secondMax < arr[j])
secondMax = arr[j];
dist.add(firstMax-secondMax);
}
}
return dist.size();
}
public static void main(String args[])
{
int arr[] = { 5 , 1 , 3 };
int n = arr.length;
System.out.println(DistinctR(arr, n));
}
}
|
Python3
def DistinctR(arr,n):
dist = set ([])
firstMax = 0
secondMax = 0
for i in range ( 0 ,n - 1 ):
firstMax = arr[i]
secondMax = - 2147483647 - 1
for j in range (i + 1 ,n):
if (firstMax<arr[j]):
secondMax = firstMax
firstMax = arr[j]
elif (secondMax<arr[j]):
secondMax = arr[j]
dist.add(firstMax - secondMax)
return len (dist)
arr = [ 5 , 1 , 3 ]
n = len (arr)
print (DistinctR(arr, n))
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int DistinctR( int [] arr, int n)
{
HashSet< int > dist = new HashSet< int >();
int firstMax, secondMax;
for ( int i = 0; i < n - 1; i++) {
firstMax = arr[i];
secondMax = Int32.MinValue;
for ( int j = i + 1; j < n; j++) {
if (firstMax < arr[j]) {
secondMax = firstMax;
firstMax = arr[j];
}
else if (secondMax < arr[j])
secondMax = arr[j];
dist.Add(firstMax - secondMax);
}
}
return dist.Count;
}
static void Main()
{
int [] arr = { 5, 1, 3 };
int n = 3;
Console.Write(DistinctR(arr, n));
}
}
|
Javascript
function DistinctR( arr,n)
{
const dist = new Set();
let firstMax, secondMax;
for (let i = 0; i < n - 1; i++)
{
firstMax = arr[i];
secondMax = Number. MIN_VALUE ;
for (let j = i + 1; j < n; j++)
{
if (firstMax < arr[j])
{
secondMax = firstMax;
firstMax = arr[j];
}
else if (secondMax < arr[j])
secondMax = arr[j];
dist.add(firstMax - secondMax);
}
}
return dist.size;
}
let arr = [5, 1, 3];
console.log(DistinctR(arr, 3));
|
Time Complexity: O(n^2)
Auxiliary Space: O(n^2)
Efficient Approach: The problem can be solved in basis of the following observation. Only the first and the second maximum are required for each subarray. When one other maximum element comes in the subarray the maximum values need to be updated. The concept of stack is used to implement this observation. Follow the steps below to solve this problem.
- Store the next greater element to the left and next greater element to the right of every array element in two arrays.
- Find the difference between next greater element to left and original element at that index ,and difference between next greater element to right and original element at that index and store in a set which contains unique values.
- Print the size of the set
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
int countUnique(vector< int >& arr, int n)
{
vector< int > ngl(n, 0);
vector< int > ngr(n, 0);
stack< int > st;
set< int > s;
ngl[0] = -1;
st.push(arr[0]);
for ( int i = 1; i < n; i++) {
while (st.size() > 0 && arr[i] > st.top()) {
st.pop();
}
if (st.size() == 0) {
ngl[i] = -1;
}
else {
ngl[i] = st.top();
}
st.push(arr[i]);
}
while (st.size() > 0) {
st.pop();
}
ngr[n - 1] = -1;
st.push(arr[n - 1]);
for ( int i = n - 2; i >= 0; i--) {
while (st.size() > 0 && arr[i] >= st.top()) {
st.pop();
}
if (st.size() != 0) {
ngr[i] = st.top();
}
else {
ngr[i] = -1;
}
st.push(arr[i]);
}
for ( int i = 0; i < n; i++) {
if (ngl[i] != -1) {
s.insert(ngl[i] - arr[i]);
}
if (ngr[i] != -1) {
s.insert(ngr[i] - arr[i]);
}
}
return s.size();
}
int main()
{
int N = 4;
vector< int > arr = { 5, 2, 3, 8 };
cout << (countUnique(arr, N));
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
public static int countUnique( int arr[], int n)
{
int [] ngl = new int [n];
int [] ngr = new int [n];
Stack<Integer> st = new Stack<>();
HashSet<Integer> s = new HashSet<>();
ngl[ 0 ] = - 1 ;
st.push(arr[ 0 ]);
for ( int i = 1 ; i < n; i++) {
while (st.size() > 0 &&
arr[i] > st.peek()) {
st.pop();
}
if (st.size() == 0 ) {
ngl[i] = - 1 ;
}
else {
ngl[i] = st.peek();
}
st.push(arr[i]);
}
while (st.size() > 0 ) {
st.pop();
}
ngr[n - 1 ] = - 1 ;
st.push(arr[n - 1 ]);
for ( int i = n - 2 ; i >= 0 ; i--) {
while (st.size() > 0 &&
arr[i] >= st.peek()) {
st.pop();
}
if (st.size() != 0 ) {
ngr[i] = st.peek();
}
else {
ngr[i] = - 1 ;
}
st.push(arr[i]);
}
for ( int i = 0 ; i < n; i++) {
if (ngl[i] != - 1 ) {
s.add(ngl[i] - arr[i]);
}
if (ngr[i] != - 1 ) {
s.add(ngr[i] - arr[i]);
}
}
return s.size();
}
public static void main(String[] args)
{
int N = 4 ;
int arr[] = { 5 , 2 , 3 , 8 };
System.out.println(countUnique(
arr, N));
}
}
|
Python3
def countUnique(arr, n):
ngl = [ 0 ] * (n)
ngr = [ 0 ] * (n)
st = []
s = set ([])
ngl[ 0 ] = - 1
st.append(arr[ 0 ])
for i in range ( 1 , n):
while ( len (st) > 0 and arr[i] > st[ - 1 ]):
st.pop()
if ( len (st) = = 0 ):
ngl[i] = - 1
else :
ngl[i] = st[ - 1 ]
st.append(arr[i])
while ( len (st) > 0 ):
st.pop()
ngr[n - 1 ] = - 1
st.append(arr[n - 1 ])
for i in range (n - 2 , - 1 , - 1 ):
while ( len (st) > 0 and arr[i] > = st[ - 1 ]):
st.pop()
if ( len (st) ! = 0 ):
ngr[i] = st[ - 1 ]
else :
ngr[i] = - 1
st.append(arr[i])
for i in range (n):
if (ngl[i] ! = - 1 ):
s.add(ngl[i] - arr[i])
if (ngr[i] ! = - 1 ):
s.add(ngr[i] - arr[i])
return len (s)
if __name__ = = "__main__" :
N = 4
arr = [ 5 , 2 , 3 , 8 ]
print (countUnique(arr, N))
|
C#
using System;
using System.Collections.Generic;
class GFG {
public static int countUnique( int [] arr, int n)
{
int [] ngl = new int [n];
int [] ngr = new int [n];
Stack< int > st = new Stack< int >();
HashSet< int > s = new HashSet< int >();
ngl[0] = -1;
st.Push(arr[0]);
for ( int i = 1; i < n; i++) {
while (st.Count > 0 &&
arr[i] > st.Peek()) {
st.Pop();
}
if (st.Count == 0) {
ngl[i] = -1;
}
else {
ngl[i] = st.Peek();
}
st.Push(arr[i]);
}
while (st.Count > 0) {
st.Pop();
}
ngr[n - 1] = -1;
st.Push(arr[n - 1]);
for ( int i = n - 2; i >= 0; i--) {
while (st.Count > 0 &&
arr[i] >= st.Peek()) {
st.Pop();
}
if (st.Count != 0) {
ngr[i] = st.Peek();
}
else {
ngr[i] = -1;
}
st.Push(arr[i]);
}
for ( int i = 0; i < n; i++) {
if (ngl[i] != -1) {
s.Add(ngl[i] - arr[i]);
}
if (ngr[i] != -1) {
s.Add(ngr[i] - arr[i]);
}
}
return s.Count;
}
public static void Main()
{
int N = 4;
int [] arr = { 5, 2, 3, 8 };
Console.Write(countUnique(arr, N));
}
}
|
Javascript
<script>
function countUnique(arr, n) {
let ngl = new Array(n).fill(0);
let ngr = new Array(n).fill(0);
let st = [];
let s = new Set();
ngl[0] = -1;
st.push(arr[0]);
for (let i = 1; i < n; i++) {
while (st.length > 0 && arr[i] > st[st.length - 1]) {
st.pop();
}
if (st.length == 0) {
ngl[i] = -1;
}
else {
ngl[i] = st[st.length - 1];
}
st.push(arr[i]);
}
while (st.length > 0) {
st.pop();
}
ngr[n - 1] = -1;
st.push(arr[n - 1]);
for (let i = n - 2; i >= 0; i--) {
while (st.length > 0 && arr[i] >= st[st.length - 1]) {
st.pop();
}
if (st.length != 0) {
ngr[i] = st[st.length - 1];
}
else {
ngr[i] = -1;
}
st.push(arr[i]);
}
for (let i = 0; i < n; i++) {
if (ngl[i] != -1) {
s.add(ngl[i] - arr[i]);
}
if (ngr[i] != -1) {
s.add(ngr[i] - arr[i]);
}
}
return s.size;
}
let N = 4;
let arr = [5, 2, 3, 8];
document.write(countUnique(arr, N));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...