Open In App

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

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:

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:

Below is the implementation of the above approach:




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




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.




# 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 = " ")




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




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

 


Article Tags :