Find last remaining element of Array after sorting and subtracting adjacents repeatedly
Last Updated :
26 Feb, 2023
Given an array arr[] of length N containing non negative integers, the task is to find the last remaining element after performing the following operations (N – 1) times:
- Sort the array in ascending order.
- Replace each element arr[i] with arr[i + 1] – arr[i], for i in [0, N – 2].
- Remove the last element, arr[n-1].
Examples:
Input: arr[] = {5, 2, 1}, N = 3
Output: 2
Explanation:
1st Operation: Sorting: arr[] = {1, 2, 5}
Replacing: arr[] = {1, 3}
2nd Operation: Sorting: arr[] = {1, 3}
Replacing: arr[] = {2}
Input: arr[] = {6, 5, 2, 3, 9, 10}, N = 6
Output: 1
Explanation:
1st Operation: Sorting: arr[] = {2, 3, 5, 6, 9, 10}
Replacing: arr[] = {1, 2, 1, 3, 1}
2nd Operation: Sorting: arr[] = {1, 1, 1, 2, 3}
Replacing: arr[] = {0, 0, 1, 1}
3rd Operation: Sorting: arr[] = {0, 0, 1, 1}
Replacing: arr[] = {0, 1, 0}
4th Operation: Sorting: arr[] = {0, 0, 1}
Replacing: arr[] = {0, 1}
5th Operation: Sorting: arr[] = {0, 1}
Replacing: arr[] = {1}
Therefore, the final answer is 1.
Approach: The basic approach to solve this problem is to sort the array each time and perform the given operation. Follow the below steps to implement that:
- Running a loop for (N – 1) times
- In each iteration, sort the array.
- Then, replace each arr[i] with arr[i+1] – arr[i] for 0 <= i <N-1.
- Decrement N by 1.
- Return the final remaining element.
Below is the implementation for the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int getFinalElem(vector< int >& Arr, int L)
{
for ( int i = 0; i < L - 1; i++) {
sort(begin(Arr), end(Arr));
for ( int j = 1; j < L; j++) {
Arr[j] = Arr[j] - Arr[j - 1];
}
L -= 1;
}
return (Arr[0]);
}
int main()
{
vector< int > arr = { 6, 5, 2, 3, 9, 10 };
int N = 6;
cout << getFinalElem(arr, N);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG
{
static int getFinalElem( int [] Arr, int L)
{
for ( int i = 0 ; i < L - 1 ; i++) {
Arrays.sort(Arr);
for ( int j = 1 ; j < L; j++) {
Arr[j] = Arr[j] - Arr[j - 1 ];
}
L -= 1 ;
}
return (Arr[ 0 ]);
}
public static void main(String[] args)
{
int [] arr = { 6 , 5 , 2 , 3 , 9 , 10 };
int N = 6 ;
System.out.println(getFinalElem(arr, N));
}
}
|
Python3
def getFinalElem(Arr, L):
for i in range (L - 1 ):
Arr.sort()
Arr = [Arr[i] - Arr[i - 1 ]
for i in range ( 1 , L)]
L - = 1
return (Arr[ 0 ])
if __name__ = = '__main__' :
arr = [ 6 , 5 , 2 , 3 , 9 , 10 ]
N = 6
print (getFinalElem(arr, N))
|
C#
using System;
class GFG
{
static int getFinalElem( int [] Arr, int L)
{
for ( int i = 0; i < L - 1; i++) {
Array.Sort(Arr);
for ( int j = 1; j < L; j++) {
Arr[j] = Arr[j] - Arr[j - 1];
}
L -= 1;
}
return (Arr[0]);
}
public static void Main()
{
int [] arr = { 6, 5, 2, 3, 9, 10 };
int N = 6;
Console.Write(getFinalElem(arr, N));
}
}
|
Javascript
<script>
let N;
function getFinalElem(Arr,L)
{
for (let i = 0; i < L - 1; i++) {
Arr.sort((a,b)=>a-b);
for (let j = 1; j < L; j++) {
Arr[j] = Arr[j] - Arr[j - 1];
}
L -= 1;
}
return Arr[0];
}
let arr = [ 6, 5, 2, 3, 9, 10 ];
N = 6;
document.write(getFinalElem(arr, N));
</script>
|
Time Complexity: O(N2 * logN)
Auxiliary Space: O(1)
Another Approach: The problem can be solved efficiently using prefix sum based on the below observation:
Suppose, that after the Kth operation, there are p non zero elements, arr[i] ≤ arr[i + 1] ≤ arr[i + 2] ≤ ….. ≤ arr[p – 3] ≤ arr[p – 2] ≤ arr[p – 1].
- Then, after the (K- 1)th operation, before the array was sorted again, there were p non zero elements, which are, at the minimum, arr[i] ≤ arr[i + 1] + arr[i] ≤ arr[i + 2] + arr[i + 1] + arr[i] ≤ …….. ≤ arr[i] + . . . + arr[p – 1]. This is because, these would have to be the minimum elements for their resultant differences to be same as after the Kth operation. This uses the concept of calculation of prefix sums.
- It can observed that the number of elements that are 0 would increase after each successive operation. For large values of N, the elements of the original array would have to be incredibly large for there to be many non-zero elements.
- The zero elements would not change due to the operations performed, so we can improve the naive approach by keeping the track of the zero elements, and performing the operations on the rest of the elements.
Note: This approach is not always efficient. This condition works efficiently only when number of 0s in the array is considerably more.
Follow the below steps to implement the observation:
- Initialise a variable (say zeroCount) to store the count of zero.
- Traverse the array to perform (N-1) operations:
- Sort the array.
- Take one vector to temporarily store the array in each step (say ModifiedArr).
- If zeroCount > 0, then decrement that by 1 and push arr[0] (which will be 0) in ModifiedArr.
- Traverse the array:
- If arr[i] = arr[i+1] then increment zeroCount by one.
- Else push arr[i+1] – arr[i] in ModifiedArr.
- Make arr = ModifiedArr.
- If zerCount > 0 the return 0.
- Otherwise, Return arr[0].
Below is the code for above implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int getFinalElem(vector< int > Arr, int L)
{
int zeroCount = 0;
for ( int j = 0; j < L - 1; j++) {
sort(Arr.begin(), Arr.end());
vector< int > ModifiedArr;
if (zeroCount > 0) {
zeroCount--;
ModifiedArr.push_back(Arr[0]);
}
for ( int i = 1; i < Arr.size(); ++i) {
if (Arr[i] == Arr[i - 1]) {
zeroCount++;
}
else {
ModifiedArr.push_back(Arr[i] - Arr[i - 1]);
}
}
Arr = ModifiedArr;
}
if (zeroCount)
return 0;
return Arr[0];
}
int main()
{
vector< int > arr = { 6, 5, 2, 3, 9, 10 };
int N = 6;
cout << getFinalElem(arr, N);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG
{
public static int getFinalElem(ArrayList<Integer>Arr, int L)
{
int zeroCount = 0 ;
for ( int j = 0 ; j < L - 1 ; j++)
{
Collections.sort(Arr);
ArrayList<Integer>ModifiedArr = new ArrayList<Integer>();
if (zeroCount > 0 ) {
zeroCount--;
ModifiedArr.add(Arr.get( 0 ));
}
for ( int i = 1 ; i < Arr.size(); ++i) {
if (Arr.get(i) == Arr.get(i - 1 )) {
zeroCount++;
}
else {
ModifiedArr.add(Arr.get(i) - Arr.get(i - 1 ));
}
}
Arr = ModifiedArr;
}
if (zeroCount> 0 ){
return 0 ;
}
return Arr.get( 0 );
}
public static void main(String args[]){
ArrayList<Integer>arr = new ArrayList<Integer>(Arrays.asList( 6 , 5 , 2 , 3 , 9 , 10 ));
int N = 6 ;
System.out.println(getFinalElem(arr, N));
}
}
|
Python3
def getFinalElem(Arr, L):
zeroCount = 0
for j in range (L - 1 ):
Arr.sort()
ModifiedArr = []
if (zeroCount > 0 ):
zeroCount - = 1
ModifiedArr.append(Arr[ 0 ])
for i in range ( 1 , len (Arr)):
if (Arr[i] = = Arr[i - 1 ]):
zeroCount + = 1
else :
ModifiedArr.append(Arr[i] - Arr[i - 1 ])
Arr = ModifiedArr
if (zeroCount):
return 0
return Arr[ 0 ]
arr = [ 6 , 5 , 2 , 3 , 9 , 10 ]
N = 6
print (getFinalElem(arr, N))
|
C#
using System;
using System.Collections.Generic;
public class GFG {
public static int getFinalElem(List< int > Arr, int L)
{
int zeroCount = 0;
for ( int j = 0; j < L - 1; j++) {
Arr.Sort();
List< int > ModifiedArr = new List< int >();
if (zeroCount > 0) {
zeroCount--;
ModifiedArr.Add(Arr[0]);
}
for ( int i = 1; i < Arr.Count; ++i) {
if (Arr[i] == Arr[i - 1]) {
zeroCount++;
}
else {
ModifiedArr.Add(Arr[i] - Arr[i - 1]);
}
}
Arr = ModifiedArr;
}
if (zeroCount > 0) {
return 0;
}
return Arr[0];
}
public static void Main( string [] args)
{
List< int > arr = new List< int >(
new int [] { 6, 5, 2, 3, 9, 10 });
int N = 6;
Console.WriteLine(getFinalElem(arr, N));
}
}
|
Javascript
<script>
const getFinalElem = (Arr, L) => {
let zeroCount = 0;
for (let j = 0; j < L - 1; j++) {
Arr.sort((a, b) => a - b);
let ModifiedArr = [];
if (zeroCount > 0) {
zeroCount--;
ModifiedArr.push(Arr[0]);
}
for (let i = 1; i < Arr.length; ++i) {
if (Arr[i] == Arr[i - 1]) {
zeroCount++;
}
else {
ModifiedArr.push(Arr[i] - Arr[i - 1]);
}
}
Arr = [...ModifiedArr];
}
if (zeroCount)
return 0;
return Arr[0];
}
let arr = [6, 5, 2, 3, 9, 10];
let N = 6;
document.write(getFinalElem(arr, N));
</script>
|
Time Complexity: O(N* M * logM), where M is the number of maximum non-zero numbers [M = N in worst situation]
Auxiliary Space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...