Given an array arr[] of size N, the task is to find the final array by repeatedly performing the following operations if two elements of opposite signs are adjacent:
- Remove both opposite signed elements from the array and insert the element having maximum absolute value along with its sign.
- If both the elements have the same absolute value, both will be removed from the array.
Examples:
Input: arr[] = {10, -5, -8, 2, -5}
Output: 10
Explanation :
At Index 0 : Element 10 has positive sign.
At Index 1 : -5 has lesser absolute value than 10. Replace both of them with 10.
At Index 2 : -8 has lesser absolute value than 10. Replace both of them with 10.
At Index 3 : 2 has positive sign. So it will be in the array.
At Index 4 : -5 has greater absolute value than 2. Replace both of them with 5.
Now -5 has lesser absolute value than 10. Replace both of them with 10.Input: arr[] = {5, -5, -2, -10}
Output: -2 -10
Explanation: 1st and 2nd element gets discarded because
both elements have same values but opposite sign.
3rd and 4th elements have same sign. So both will be in the array.
Approach: The problem can be solved by using the following idea:
At any moment the previous elements can also be required, so a Stack data structure can be used to hold the elements, and smaller elements can be popped efficiently from the stack due to its last-in-first-out property.
Look at the below illustration for a better understanding:
Consider array arr[] = {10, -5, -8, 2, -5}.
Initially stack is empty, st = { }
At 0th index:
=> arr[0] = 10
=> st = {}
=> Push 10 into the stack
=> The stack is st = {10}At 1st index:
=> arr[1] = -5
=> st = {10}
=> The top most element of stack is positive and arr[1] is negative.
=> As arr[1] has lesser absolute value i.e. 5 than top most element of stack so no changes in stack.
=> The stack is st = {10}At 2nd index:
=> arr[2] = -8
=> st = {10}
=> The top most element of stack is positive and arr[2] is negative.
=> As arr[2] has lesser absolute value i.e. 8 than top most element of stack so no changes in stack.
=> The stack is st = {10}At 3rd index:
=> arr[3] = 2
=> The top most element of stack is positive and arr[3] is also positive.
=> Push 2 in the stack.
=> The stack is st = {10, 2}At 4th index:
=> arr[4] = -5
=> st = {10, 2}
=> The top most element of stack is positive and arr[4] is negative.
=> As arr[4] has greater absolute value i.e. 5 than top most element of stack, pop the top most element of stack.
=> The stack changes from st = {10, 2} to st = {10}
=> Now again, the top most element of stack is positive and arr[4] is negative.
=> arr[4] has lesser absolute value i.e. 5 than top most element. So no changes in stack.
=> The stack remains st = {10}The elements finally remaining in the stack are the final elements of the array.
So the elements remaining in the array are arr = {10}
Follow the steps mentioned below to implement the approach:
- Declare a stack to hold the array elements.
- Traverse the array, If the element is positive, directly push onto the stack.
- Else if current arr[i] is negative, then
- Try popping all the smaller elements from the stack which are positive, stating that the element having smaller absolute value has been discarded.
- If the current element and top of the stack are equal and the top of the stack is positive then pop from the stack, stating that both elements with equal values but the opposite sign has been discarded.
- Lastly, If the stack is empty or the last element is negative, then push the current arr[i] element on the stack. As all remaining elements will have a negative sign.
- Finally, return the stack, showing the remaining elements.
Below is the implementation of the above approach:
C++
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std; class Solution { public : // Function to find the remaining elements vector< int > solve(vector< int >& arr) { // Stack to store elements vector< int > st; // Traverse entire array for ( auto element : arr) { // If positive element, // directly push if (element >= 0) st.push_back(element); else { // Pop all the smaller elements // moving in the right direction while (st.size() > 0 && st.back() >= 0 && abs (element) > st.back()) st.pop_back(); // Top of stack and current // element same value and top of // stack moving in right direction if (st.size() > 0 && st.back() >= 0 && st.back() == abs (element)) st.pop_back(); // No more elements remaining or // remaining elements // moving in left direction else if (st.size() == 0 || st.back() < 0) st.push_back(element); } } // Finally return stack return st; } }; // Driver code int main() { Solution obj; vector< int > arr = { 5, -5, -2, -10 }; vector< int > ans = obj.solve(arr); for ( auto x : ans) cout << x << " " ; return 0; } // This code is contributed by rakeshsahni |
Java
import java.util.*; import java.io.*; class GFG{ // Function to find remaining element public static ArrayList<Integer> solve(ArrayList<Integer> arr){ // Stack to store elements ArrayList<Integer> st = new ArrayList<Integer>(); // Traverse entire array for (Integer element: arr){ // If positive element, // directly push if (element >= 0 ) { st.add(element); } else { // Pop all the smaller elements // moving in the right direction while (st.size()> 0 && st.get(st.size()- 1 ) >= 0 && Math.abs(element) > st.get(st.size()- 1 )){ st.remove(st.size()- 1 ); } // Top of stack and current // element same value and top of // stack moving in right direction if (st.size() > 0 && st.get(st.size()- 1 ) >= 0 && st.get(st.size()- 1 ) == Math.abs(element)){ st.remove(st.size()- 1 ); } // No more elements remaining or // remaining elements // moving in left direction else if (st.size() == 0 || st.get(st.size()- 1 ) < 0 ){ st.add(element); } } } // Finally return stack return st; } // Driver code public static void main(String args[]) { // Size of array int N = 5 ; ArrayList<Integer> arr = new ArrayList<Integer>(); arr.add( 5 ); arr.add(- 5 ); arr.add(- 2 ); arr.add(- 10 ); ArrayList<Integer> ans = solve(arr); for ( int i= 0 ; i<ans.size() ; i++){ System.out.print(ans.get(i) + " " ); } } } // This code is contributed by subhamgoyal2014. |
Python3
# Python code to implement the approach class Solution: # Function to find the remaining elements def solve( self , arr): # Stack to store elements stack = [] # Traverse entire array for element in arr: # If positive element, # directly push if (element > = 0 ): stack.append(element) else : # Pop all the smaller elements # moving in the right direction while (stack and stack[ - 1 ] > = 0 \ and abs (element) > stack[ - 1 ]): stack.pop() # Top of stack and current # element same value and top of # stack moving in right direction if (stack and stack[ - 1 ] > = 0 \ and stack[ - 1 ] = = abs (element)): stack.pop() # No more elements remaining or # remaining elements # moving in left direction elif ( len (stack) = = 0 \ or stack[ - 1 ] < 0 ): stack.append(element) # Finally return stack return stack # Driver code if __name__ = = '__main__' : obj = Solution() arr = [ 5 , - 5 , - 2 , - 10 ] ans = obj.solve(arr) for x in ans: print (x, end = " " ) |
C#
using System; using System.Collections.Generic; public class GFG{ // Function to find remaining element public static List< int > solve(List< int > arr){ // Stack to store elements List< int > st = new List< int >(); // Traverse entire array foreach ( int element in arr){ // If positive element, // directly push if (element >= 0) { st.Add(element); } else { // Pop all the smaller elements // moving in the right direction while (st.Count>0 && st[st.Count-1] >= 0 && Math.Abs(element) > st[st.Count-1]){ st.RemoveAt(st.Count-1); } // Top of stack and current // element same value and top of // stack moving in right direction if (st.Count > 0 && st[st.Count-1] >= 0 && st[st.Count-1] == Math.Abs(element)){ st.RemoveAt(st.Count-1); } // No more elements remaining or // remaining elements // moving in left direction else if (st.Count == 0 || st[st.Count-1] < 0){ st.Add(element); } } } // Finally return stack return st; } // Driver code public static void Main(String []args) { // Size of array int N = 5; List< int > arr = new List< int >(); arr.Add(5); arr.Add(-5); arr.Add(-2); arr.Add(-10); List< int > ans = solve(arr); for ( int i = 0; i < ans.Count; i++){ Console.Write(ans[i] + " " ); } } } // This code is contributed by shikhasingrajput |
Javascript
<script> // JavaScript code to implement the approach class Solution { // Function to find the remaining elements solve(arr) { // Stack to store elements let st = []; // Traverse entire array for (let element of arr) { // If positive element, // directly push if (element >= 0) st.push(element); else { // Pop all the smaller elements // moving in the right direction while (st.length > 0 && st[st.length-1] >= 0 && Math.abs(element) > st[st.length-1]) st.pop(); // Top of stack and current // element same value and top of // stack moving in right direction if (st.length > 0 && st[st.length-1] >= 0 && st[st.length-1] == Math.abs(element)) st.pop(); // No more elements remaining or // remaining elements // moving in left direction else if (st.length == 0 || st[st.length-1] < 0) st.push(element); } } // Finally return stack return st; } } // Driver code let obj = new Solution(); let arr = [ 5, -5, -2, -10 ]; let ans = obj.solve(arr); for (let x of ans) document.write(x, " " ); // This code is contributed by shinjanpatra </script> |
-2 -10
Time Complexity: O(N)
Auxiliary Space: O(1)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!