Smallest subsequence with sum of absolute difference of consecutive elements maximized
Last Updated :
13 Dec, 2021
Given an array arr[] of length N, containing values in the range [1, N], the task is to find a subsequence s1, s2, ..., sk such that
\\ Sum = \mid s1 - s2 \mid + \mid s2 - s3 \mid + ... + \mid s_{k-1} - s_{k} \mid
is maximised. In case of multiple subsequences having maximum possible sum, print the smallest one.
Input: N = 3, P = {3, 2, 1}
Output: K = 2, S = {3, 1}
Explanation:
Maximum sum possible = 2
Subsequences {3, 2, 1} and {3, 1} achieves that sum.
Hence, the subsequence {3, 1} is considered being of smaller length.
Input: N = 4, P = {1, 3, 4, 2}
Output: K = 3, S = {1, 4, 2}
Explanation:
Maximum sum possible = 5
Subsequences {1, 3, 4, 2} and {1, 4, 2} achieves that sum.
Hence, the subsequence {1, 4, 2} is considered being of smaller length.
Naive Approach:
Generate all subsequences of length >= 2 and calculate their respective sums. Keep track of the maximum sum obtained for any subsequence. In the case of multiple subsequences having the maximum sum, keep updating the minimum length, and maintain that subsequence. Finally print the subsequence.
Time Complexity: O(2N)
Efficient Approach:
There are a few key observations that will help us proceed:
- The maximum sum will be obtained when all the elements in the permutation are considered.
For example:
N = 4, P = [1, 3, 4, 2]
Max sum = | 1 - 3 | + | 3 - 4 | + | 4 - 2 | = 2 + 1 + 2 = 5
Here, the length is N and the required subsequence is permutation P itself.
Now that we know the maximum possible sum, the objective is to minimize the subsequence length without affecting this maximum sum.- For a monotonically increasing or decreasing subsequence, maximum sum can be achieved by only considering the First and Last element, for example:
S = [1, 3, 5, 7]
Max sum = | 1 - 3 | + | 3 - 5 | + | 5 - 7 | = 2 + 2 + 2 = 6, K = 4
Considering only first and last element,
S = [1, 7]
Max sum = | 1 - 7 | = 6, K = 2
In this way, the length of the subsequence can be reduced without affecting the Max sum.
Hence, from the given array, keep extracting the end-points of monotonically increasing or decreasing subsequences, and add them to the subsequence in the following way:
- The first and the last element of the permutation are default endpoints
- An element P[ i ] is a monotonically increasing endpoint if P[ i - 1 ] < P[ i ] > P[ i + 1 ]
- An element P[ i ] is monotonically decreasing endpoint if P[ i - 1 ] > P[ i ] < P[ i + 1 ]
The subsequence thus obtained will have maximum sum and minimum length.
Below is the implementation of the above approach:
C++
// C++ program to find
// smallest subsequence
// with sum of absolute
// difference of consecutive
// elements maximized
#include <bits/stdc++.h>
using namespace std;
// Function to print the smallest
// subsequence and its sum
void getSubsequence(vector<int>& arr,
int n)
{
// Final subsequence
vector<int> req;
// First element is
// a default endpoint
req.push_back(arr[0]);
// Iterating through the array
for (int i = 1; i < n - 1; i++) {
// Check for monotonically
// increasing endpoint
if (arr[i] > arr[i + 1]
&& arr[i] > arr[i - 1])
req.push_back(arr[i]);
// Check for monotonically
// decreasing endpoint
else if (arr[i] < arr[i + 1]
&& arr[i] < arr[i - 1])
req.push_back(arr[i]);
}
// Last element is
// a default endpoint
req.push_back(arr[n - 1]);
// Length of final subsequence
cout << req.size() << endl;
// Print the subsequence
for (auto x : req)
cout << x << " ";
}
// Driver Program
int main()
{
vector<int> arr = { 1, 2, 5, 3,
6, 7, 4 };
int n = arr.size();
getSubsequence(arr, n);
return 0;
}
Java
// Java program to find smallest
// subsequence with sum of absolute
// difference of consecutive
// elements maximized
import java.util.*;
class GFG{
// Function to print the smallest
// subsequence and its sum
static void getSubsequence(int []arr, int n)
{
// Final subsequence
Vector<Integer> req = new Vector<Integer>();
// First element is
// a default endpoint
req.add(arr[0]);
// Iterating through the array
for(int i = 1; i < n - 1; i++)
{
// Check for monotonically
// increasing endpoint
if (arr[i] > arr[i + 1] &&
arr[i] > arr[i - 1])
req.add(arr[i]);
// Check for monotonically
// decreasing endpoint
else if (arr[i] < arr[i + 1] &&
arr[i] < arr[i - 1])
req.add(arr[i]);
}
// Last element is
// a default endpoint
req.add(arr[n - 1]);
// Length of final subsequence
System.out.print(req.size() + "\n");
// Print the subsequence
for(int x : req)
System.out.print(x + " ");
}
// Driver code
public static void main(String[] args)
{
int []arr = { 1, 2, 5, 3,
6, 7, 4 };
int n = arr.length;
getSubsequence(arr, n);
}
}
// This code is contributed by Amit Katiyar
Python3
# Python3 program to find smallest
# subsequence with sum of absolute
# difference of consecutive
# elements maximized
# Function to print the smallest
# subsequence and its sum
def getSubsequence(arr, n):
# Final subsequence
req = []
# First element is
# a default endpoint
req.append(arr[0])
# Iterating through the array
for i in range(1, n - 1):
# Check for monotonically
# increasing endpoint
if (arr[i] > arr[i + 1] and
arr[i] > arr[i - 1]):
req.append(arr[i])
# Check for monotonically
# decreasing endpoint
elif (arr[i] < arr[i + 1] and
arr[i] < arr[i - 1]):
req.append(arr[i]);
# Last element is
# a default endpoint
req.append(arr[n - 1]);
# Length of final subsequence
print(len(req))
# Print the subsequence
for x in req:
print(x, end = ' ')
# Driver code
if __name__=='__main__':
arr = [ 1, 2, 5, 3, 6, 7, 4 ]
n = len(arr)
getSubsequence(arr, n)
# This code is contributed by rutvik_56
C#
// C# program to find smallest
// subsequence with sum of absolute
// difference of consecutive
// elements maximized
using System;
using System.Collections.Generic;
class GFG{
// Function to print the smallest
// subsequence and its sum
static void getSubsequence(int []arr, int n)
{
// Final subsequence
List<int> req = new List<int>();
// First element is
// a default endpoint
req.Add(arr[0]);
// Iterating through the array
for(int i = 1; i < n - 1; i++)
{
// Check for monotonically
// increasing endpoint
if (arr[i] > arr[i + 1] &&
arr[i] > arr[i - 1])
req.Add(arr[i]);
// Check for monotonically
// decreasing endpoint
else if (arr[i] < arr[i + 1] &&
arr[i] < arr[i - 1])
req.Add(arr[i]);
}
// Last element is
// a default endpoint
req.Add(arr[n - 1]);
// Length of readonly subsequence
Console.Write(req.Count + "\n");
// Print the subsequence
foreach(int x in req)
Console.Write(x + " ");
}
// Driver code
public static void Main(String[] args)
{
int []arr = { 1, 2, 5, 3,
6, 7, 4 };
int n = arr.Length;
getSubsequence(arr, n);
}
}
// This code is contributed by Amit Katiyar
JavaScript
<script>
// JavaScript code for the above approach
// Function to print the smallest
// subsequence and its sum
function getSubsequence(arr, n)
{
// Final subsequence
let req = [];
// First element is
// a default endpoint
req.push(arr[0]);
// Iterating through the array
for (let i = 1; i < n - 1; i++) {
// Check for monotonically
// increasing endpoint
if (arr[i] > arr[i + 1]
&& arr[i] > arr[i - 1])
req.push(arr[i]);
// Check for monotonically
// decreasing endpoint
else if (arr[i] < arr[i + 1]
&& arr[i] < arr[i - 1])
req.push(arr[i]);
}
// Last element is
// a default endpoint
req.push(arr[n - 1]);
// Length of final subsequence
document.write(req.length + '<br>');
// Print the subsequence
for (let x of req)
document.write(x + " ");
}
// Driver Program
let arr = [1, 2, 5, 3,
6, 7, 4];
let n = arr.length;
getSubsequence(arr, n);
// This code is contributed by Potta Lokesh
</script>
Time complexity: O(N)
Similar Reads
Cost of creating smallest subsequence with sum of difference between adjacent elements maximum Given two array of N integers arr[] and costArray[], representing removal cost associated with each element. The task is to find the subsequence from the given array of minimum cost such that the sum of the difference between adjacent elements is maximum. On removing each element, cost is incurred.E
10 min read
Maximum Sum Subsequence made up of consecutive elements of different parity Given an array arr[] consisting of N integers, the task is to find the maximum sum of a non-empty subsequence such that each pair of consecutive terms is of different parity (even or odd). Examples: Input: arr[] = {1, 2, 6, 8, -5, 10}Output: 14Explanation: Considering the subsequence {1, 8, -5, 10}
9 min read
Sequence with sum K and minimum sum of absolute differences between consecutive elements Given two integers N and K, the task is to find a sequence of integers of length N such that the sum of all the elements of the sequence is K and the sum of absolute differences between all consecutive elements is minimum. Print this minimized sum. Examples: Input: N = 3, K = 56 Output: 1 The sequen
4 min read
Maximum Subsequence sum with difference among consecutive numbers less than K Given an array arr[], find the maximum sum that can be achieved by picking a subsequence such that the difference between consecutive elements in the subsequence is less than or equal to a given number 'K'. Examples: Input: arr[] = {1, 8, 9, 4, 6, 7}, K = 2Output: 24. Explanation: The maximum sum ca
7 min read
Maximize difference between sum of even and odd-indexed elements of a subsequence | Set 2 Given an array arr[] consisting of N positive integers, the task is to find the maximum value of the difference between the sum of elements at even and odd indices for any subsequence of the array. Note: The value of N is always greater than 1. Examples: Input: arr[] = { 3, 2, 1, 4, 5, 2, 1, 7, 8, 9
11 min read