Find last remaining element of Array after sorting and subtracting adjacents repeatedly
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> |
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> |
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)
Please Login to comment...