Open In App

Find last remaining element of Array after sorting and subtracting adjacents repeatedly

Last Updated : 26 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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++




// C++ code to implement above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to get the final element
int getFinalElem(vector<int>& Arr, int L)
{
    // Loop till only one element remains
    // ie till n is 1
    for (int i = 0; i < L - 1; i++) {
        // Sorting the array
        sort(begin(Arr), end(Arr));
 
        // Replacing arr[i] with
        // arr[i] - arr[i - 1]
        for (int j = 1; j < L; j++) {
            Arr[j] = Arr[j] - Arr[j - 1];
        }
        L -= 1;
    }
    return (Arr[0]);
}
 
// Driver Code
int main()
{
    vector<int> arr = { 6, 5, 2, 3, 9, 10 };
    int N = 6;
 
    // Function call
    cout << getFinalElem(arr, N);
    return 0;
}
 
// This code is contributed by Rohit Pradhan


Java




// Java code to implement the approach
import java.io.*;
import java.util.*;
 
class GFG
{
 
  // Function to get the final element
  static int getFinalElem(int[] Arr, int L)
  {
    // Loop till only one element remains
    // ie till n is 1
    for (int i = 0; i < L - 1; i++) {
      // Sorting the array
      Arrays.sort(Arr);
 
      // Replacing arr[i] with
      // arr[i] - arr[i - 1]
      for (int j = 1; j < L; j++) {
        Arr[j] = Arr[j] - Arr[j - 1];
      }
      L -= 1;
    }
    return (Arr[0]);
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    int[] arr = { 6, 5, 2, 3, 9, 10 };
    int N = 6;
 
    // Function call
    System.out.println(getFinalElem(arr, N));
 
  }
}
 
// This code is contributed by sanjoy_62.


Python3




# Python3 code to implement above approach
 
# Function to get the final element
def getFinalElem(Arr, L):
         
    # Loop till only one element remains
    # ie till n is 1
    for i in range(L - 1):
         
        # Sorting the array
        Arr.sort()
         
        # Replacing arr[i] with
        # arr[i] - arr[i - 1]
        Arr = [Arr[i] - Arr[i - 1]
             for i in range(1, L)]
        L -= 1
 
    return (Arr[0])
 
# Driver Code
if __name__ == '__main__':
    arr = [6, 5, 2, 3, 9, 10]
    N = 6
     
    # Function call
    print(getFinalElem(arr, N))


C#




// C# program for above approach
using System;
class GFG
{
 
  // Function to get the final element
  static int getFinalElem(int[] Arr, int L)
  {
    // Loop till only one element remains
    // ie till n is 1
    for (int i = 0; i < L - 1; i++) {
      // Sorting the array
      Array.Sort(Arr);
 
      // Replacing arr[i] with
      // arr[i] - arr[i - 1]
      for (int j = 1; j < L; j++) {
        Arr[j] = Arr[j] - Arr[j - 1];
      }
      L -= 1;
    }
    return (Arr[0]);
  }
 
  // Driver Code
  public static void Main()
  {
    int[] arr = { 6, 5, 2, 3, 9, 10 };
    int N = 6;
 
    // Function call
    Console.Write(getFinalElem(arr, N));
  }
}
 
// This code is contributed by code_hunt.


Javascript




<script>
 
// JavaScript code to implement above approach
let N;
 
// Function to get the final element
function getFinalElem(Arr,L)
{
    // Loop till only one element remains
    // ie till n is 1
    for (let i = 0; i < L - 1; i++) {
        // Sorting the array
        Arr.sort((a,b)=>a-b);
         
        // Replacing arr[i] with
        // arr[i] - arr[i - 1]
        for (let j = 1; j < L; j++) {
            Arr[j] = Arr[j] - Arr[j - 1];
        }
        L -= 1;
    }
    return Arr[0];
}
 
// Driver Code
 
let arr = [ 6, 5, 2, 3, 9, 10 ];
 
N = 6;
 
// Function call
document.write(getFinalElem(arr, N));
 
// This code is contributed by shinjanpatra
 
</script>


Output

1

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++




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function that returns the final element
int getFinalElem(vector<int> Arr, int L)
{
    // Variable to store the count of zero
    // elements
    int zeroCount = 0;
 
    // Performing the L - 1 operations
    for (int j = 0; j < L - 1; j++) {
        // Sorting the array
        sort(Arr.begin(), Arr.end());
 
        // Vector to store the modified array
        // in the meanwhile
        vector<int> ModifiedArr;
 
        // If there are zero elements, then
        // we push the smallest element of
        // arr which will be zero) to the
        // modified arr before we start the
        // modifications because it will not
        // impact the results in any manner
        if (zeroCount > 0) {
            zeroCount--;
            ModifiedArr.push_back(Arr[0]);
        }
 
        // Performing the operations
        for (int i = 1; i < Arr.size(); ++i) {
 
            // If the element is the same
            // as the preceding element then
            // the new element after modification
            // will be zero and so
            // we update the zerocount
            if (Arr[i] == Arr[i - 1]) {
                zeroCount++;
            }
            else {
                ModifiedArr.push_back(Arr[i] - Arr[i - 1]);
            }
        }
 
        // Updating the array with
        // the modified array
        Arr = ModifiedArr;
    }
    // If even after the L - 1 operations
    // there is still a zerocount > 0,
    // then that means Arr[0] = 0.
    if (zeroCount)
        return 0;
    return Arr[0];
}
 
// Driver Code
int main()
{
    vector<int> arr = { 6, 5, 2, 3, 9, 10 };
    int N = 6;
 
    // Function call
    cout << getFinalElem(arr, N);
    return 0;
}


Java




/*package whatever //do not write package name here */
import java.io.*;
import java.util.*;
 
class GFG
{
   
  // Function that returns the final element
  public static int getFinalElem(ArrayList<Integer>Arr, int L)
  {
     
    // Variable to store the count of zero
    // elements
    int zeroCount = 0;
 
    // Performing the L - 1 operations
    for (int j = 0; j < L - 1; j++)
    {
       
      // Sorting the array
      Collections.sort(Arr);
 
      // Vector to store the modified array
      // in the meanwhile
      ArrayList<Integer>ModifiedArr = new ArrayList<Integer>();
 
      // If there are zero elements, then
      // we push the smallest element of
      // arr which will be zero) to the
      // modified arr before we start the
      // modifications because it will not
      // impact the results in any manner
      if (zeroCount > 0) {
        zeroCount--;
        ModifiedArr.add(Arr.get(0));
      }
 
      // Performing the operations
      for (int i = 1; i < Arr.size(); ++i) {
 
        // If the element is the same
        // as the preceding element then
        // the new element after modification
        // will be zero and so
        // we update the zerocount
        if (Arr.get(i) == Arr.get(i - 1)) {
          zeroCount++;
        }
        else {
          ModifiedArr.add(Arr.get(i) - Arr.get(i - 1));
        }
      }
 
      // Updating the array with
      // the modified array
      Arr = ModifiedArr;
    }
    // If even after the L - 1 operations
    // there is still a zerocount > 0,
    // then that means Arr[0] = 0.
    if (zeroCount>0){
      return 0;
    }
    return Arr.get(0);
  }
 
  // Drivers code
  public static void main(String args[]){
 
    ArrayList<Integer>arr = new ArrayList<Integer>(Arrays.asList(6, 5, 2, 3, 9, 10 ));
    int N = 6;
 
    // Function call
    System.out.println(getFinalElem(arr, N));
 
  }
}
 
// This code is contributed by shinjanpatra.


Python3




# Python code to implement the approach
 
# Function that returns the final element
def getFinalElem(Arr, L):
 
    # Variable to store the count of zero
    # elements
    zeroCount = 0
 
    # Performing the L - 1 operations
    for j in range(L - 1):
        # Sorting the array
        Arr.sort()
 
        # Vector to store the modified array
        # in the meanwhile
        ModifiedArr = []
 
        # If there are zero elements, then
        # we push the smallest element of
        # arr which will be zero) to the
        # modified arr before we start the
        # modifications because it will not
        # impact the results in any manner
        if (zeroCount > 0):
            zeroCount -= 1
            ModifiedArr.append(Arr[0])
 
        # Performing the operations
        for i in range(1,len(Arr)):
 
            # If the element is the same
            # as the preceding element then
            # the new element after modification
            # will be zero and so
            # we update the zerocount
            if (Arr[i] == Arr[i - 1]):
                zeroCount += 1
         
            else:
                ModifiedArr.append(Arr[i] - Arr[i - 1])
             
 
        # Updating the array with
        # the modified array
        Arr = ModifiedArr
         
    # If even after the L - 1 operations
    # there is still a zerocount > 0,
    # then that means Arr[0] = 0.
    if (zeroCount):
        return 0
    return Arr[0]
 
# Driver Code
arr = [6, 5, 2, 3, 9, 10]
N = 6
 
# Function call
print(getFinalElem(arr, N))
 
# This code is contributed by shinjanpatra


C#




// C# code to implement the approach
using System;
using System.Collections.Generic;
 
public class GFG {
 
  // Function that returns the final element
  public static int getFinalElem(List<int> Arr, int L)
  {
 
    // Variable to store the count of zero
    // elements
    int zeroCount = 0;
 
    // Performing the L - 1 operations
    for (int j = 0; j < L - 1; j++) {
 
      // Sorting the array
      Arr.Sort();
 
      // Vector to store the modified array
      // in the meanwhile
      List<int> ModifiedArr = new List<int>();
 
      // If there are zero elements, then
      // we push the smallest element of
      // arr which will be zero) to the
      // modified arr before we start the
      // modifications because it will not
      // impact the results in any manner
      if (zeroCount > 0) {
        zeroCount--;
        ModifiedArr.Add(Arr[0]);
      }
 
      // Performing the operations
      for (int i = 1; i < Arr.Count; ++i) {
 
        // If the element is the same
        // as the preceding element then
        // the new element after modification
        // will be zero and so
        // we update the zerocount
        if (Arr[i] == Arr[i - 1]) {
          zeroCount++;
        }
        else {
          ModifiedArr.Add(Arr[i] - Arr[i - 1]);
        }
      }
 
      // Updating the array with
      // the modified array
      Arr = ModifiedArr;
    }
    // If even after the L - 1 operations
    // there is still a zerocount > 0,
    // then that means Arr[0] = 0.
    if (zeroCount > 0) {
      return 0;
    }
    return Arr[0];
  }
 
  // Driver Code
  public static void Main(string[] args)
  {
    List<int> arr = new List<int>(
      new int[] { 6, 5, 2, 3, 9, 10 });
    int N = 6;
 
    // Function call
    Console.WriteLine(getFinalElem(arr, N));
  }
}
 
// This code is contributed by phasing17


Javascript




<script>
    // JavaScript code to implement the approach
 
    // Function that returns the final element
    const getFinalElem = (Arr, L) => {
        // Variable to store the count of zero
        // elements
        let zeroCount = 0;
 
        // Performing the L - 1 operations
        for (let j = 0; j < L - 1; j++) {
            // Sorting the array
            Arr.sort((a, b) => a - b);
 
            // Vector to store the modified array
            // in the meanwhile
            let ModifiedArr = [];
 
            // If there are zero elements, then
            // we push the smallest element of
            // arr which will be zero) to the
            // modified arr before we start the
            // modifications because it will not
            // impact the results in any manner
            if (zeroCount > 0) {
                zeroCount--;
                ModifiedArr.push(Arr[0]);
            }
 
            // Performing the operations
            for (let i = 1; i < Arr.length; ++i) {
                // If the element is the same
                // as the preceding element then
                // the new element after modification
                // will be zero and so
                // we update the zerocount
                if (Arr[i] == Arr[i - 1]) {
                    zeroCount++;
                }
                else {
                    ModifiedArr.push(Arr[i] - Arr[i - 1]);
                }
            }
 
            // Updating the array with
            // the modified array
            Arr = [...ModifiedArr];
        }
        // If even after the L - 1 operations
        // there is still a zerocount > 0,
        // then that means Arr[0] = 0.
 
        if (zeroCount)
            return 0;
        return Arr[0];
    }
 
    // Driver Code
 
    let arr = [6, 5, 2, 3, 9, 10];
    let N = 6;
 
    // Function call
    document.write(getFinalElem(arr, N));
 
// This code is contributed by rakeshsahni
 
</script>


Output

1

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

Similar Reads