Open In App

Reduce Array by replacing adjacent opposite sign pairs with their absolute maximum

Last Updated : 02 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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>


 
 

Output

-2 -10 

 

Time Complexity: O(N)
Auxiliary Space: O(1)

 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads