Opposite Sign Pair Reduction

Last Updated : 24 Apr, 2026

Given an array arr[] of size n, the task is to find the final array by repeatedly performing the following operations from left to right and check, If two adjacent elements have opposite signs:

  • Remove both elements and insert the element with the larger absolute value, along with its sign.
  • If both elements have the same absolute value, remove both without inserting anything.

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.

Try It Yourself
redirect icon

[Naive Approach] Iterative Method - O(n^2) Time and O(1) Space

The idea is to repeatedly scan the array from left to right and resolve only the first adjacent opposite sign pair by keeping the element with larger absolute value or removing both if equal. After each modification, restart the scan from the beginning since new adjacent pairs may form. Continue this process until no more such pairs exist in the array.

Dry run for arr[] = [10, -5, -8, 2, -5]:

  1. For i = 0, elements 10 and -5 have opposite signs and |10| > |−5|, so keep 10, Array becomes [10, -8, 2, -5]
  2. For i = 0, elements 10 and -8 have opposite signs and |10| > |−8|, so keep 10, Array becomes [10, 2, -5]
  3. For i = 0, elements 10 and 2 have same sign, so move ahead
  4. For i = 1, elements 2 and -5 have opposite signs and |−5| > |2|, so keep -5, Array becomes [10, -5]
  5. For i = 0, elements 10 and -5 have opposite signs and |10| > |−5|, so keep 10, Array becomes [10]
  6. No more pairs exist, process stops

Final array is [10]

C++
#include <iostream>
#include <vector>
using namespace std;

vector<int> reducePairs(vector<int>& arr) {
    bool changed = true;

    while (changed) {
        changed = false;
        vector<int> temp;

        for (int i = 0; i < arr.size(); i++) {
            
            // check next element exists and signs are opposite
            if (i + 1 < arr.size() && arr[i] * arr[i + 1] < 0) {
                
                int a = arr[i], b = arr[i + 1];

                if (abs(a) > abs(b)) {
                    temp.push_back(a);
                }
                else if (abs(a) < abs(b)) {
                    temp.push_back(b);
                }
                
                // if equal, both removed (do nothing)
                // copy remaining elements as it is
                for (int j = i + 2; j < arr.size(); j++) {
                    temp.push_back(arr[j]);
                }
                
                changed = true;
                break;
            }
            else {
                temp.push_back(arr[i]);
            }
        }
        
        // if no pair found, array remains same
        if (changed)
            arr = temp;
    }

    return arr;
}

int main() {
    vector<int> arr = {10, -5, -8, 2, -5};  

    vector<int> result = reducePairs(arr);  

    for (int i = 0; i < result.size(); i++) {
        cout << result[i] << " ";
    }

    return 0;
}
Java
import java.util.ArrayList;
import java.util.List;

class GfG {
    static ArrayList<Integer> reducePairs(int[] arr) {
        boolean changed = true;

        // convert array to list for easier manipulation
        ArrayList<Integer> list = new ArrayList<>();
        for (int x : arr) list.add(x);

        while (changed) {
            changed = false;
            ArrayList<Integer> temp = new ArrayList<>();

            for (int i = 0; i < list.size(); i++) {
                
                // check next element exists and signs are opposite
                if (i + 1 < list.size() 
                            && list.get(i) * list.get(i + 1) < 0) {
                    
                    int a = list.get(i), b = list.get(i + 1);

                    if (Math.abs(a) > Math.abs(b)) {
                        temp.add(a);
                    } 
                    else if (Math.abs(a) < Math.abs(b)) {
                        temp.add(b);
                    }
                    
                    // if equal, both removed (do nothing)
                    // copy remaining elements as it is
                    for (int j = i + 2; j < list.size(); j++) {
                        temp.add(list.get(j));
                    }
                    
                    changed = true;
                    break;
                } 
                else {
                    temp.add(list.get(i));
                }
            }
            
            // if no pair found, array remains same
            if (changed)
                list = temp;
        }

        return list;
    }

    public static void main(String[] args) {
        int[] arr = {10, -5, -8, 2, -5};

        ArrayList<Integer> result = reducePairs(arr);

        for (int x : result) {
            System.out.print(x + " ");
        }
    }
}
Python
def reducePairs(arr):
    changed = True

    while changed:
        changed = False
        temp = []

        for i in range(len(arr)):
            
            # check next element exists and signs are opposite
            if i + 1 < len(arr) and arr[i] * arr[i + 1] < 0:
                a = arr[i]
                b = arr[i + 1]

                if abs(a) > abs(b):
                    temp.append(a)
                elif abs(a) < abs(b):
                    temp.append(b)
                    
                # if equal, both removed (do nothing)
                # append remaining elements
                temp.extend(arr[i + 2:])
                
                changed = True
                break
            else:
                temp.append(arr[i])
                
        # if no pair found, array remains same
        if changed:
            arr = temp 
    return arr

if __name__ == '__main__':
    arr = [10, -5, -8, 2, -5]
    result = reducePairs(arr)
    
    for i in range(len(result)):
        print(result[i], end=' ')
C#
using System;
using System.Collections.Generic;

class GfG
{
    static List<int> reducePairs(int[] arr)
    {
        bool changed = true;

        // convert array to list for easier updates
        List<int> list = new List<int>(arr);

        while (changed)
        {
            changed = false;
            List<int> temp = new List<int>();

            for (int i = 0; i < list.Count; i++)
            {
                if (i + 1 < list.Count && list[i] * list[i + 1] < 0)
                {
                    int a = list[i], b = list[i + 1];

                    if (Math.Abs(a) > Math.Abs(b))
                        temp.Add(a);
                        
                    else if (Math.Abs(a) < Math.Abs(b))
                        temp.Add(b);
                        
                    // if equal, both removed (do nothing)
                    // copy remaining elements directly
                    for (int j = i + 2; j < list.Count; j++)
                        temp.Add(list[j]);
    
                    changed = true;
                    break;
                }
                else
                {
                    temp.Add(list[i]);
                }
            }

            // if no pair found, array remains same
            if (changed)
                list = temp;
        }

        return list;
    }

    public static void Main()
    {
        int[] arr = { 10, -5, -8, 2, -5 };

        List<int> result = reducePairs(arr);

        foreach (int x in result)
        {
            Console.Write(x + " ");
        }
    }
}
JavaScript
function reducePairs(arr) {
    let changed = true;

    while (changed) {
        changed = false;
        let temp = [];

        for (let i = 0; i < arr.length; i++) {
            
            // check next element exists and signs are opposite
            if (i + 1 < arr.length && arr[i] * arr[i + 1] < 0) {
                let a = arr[i], b = arr[i + 1];

                if (Math.abs(a) > Math.abs(b)) {
                    temp.push(a);
                } 
                else if (Math.abs(a) < Math.abs(b)) {
                    temp.push(b);
                }
                
                // if equal → both removed (do nothing)
                // copy remaining elements
                for (let j = i + 2; j < arr.length; j++) {
                    temp.push(arr[j]);
                }

                changed = true;
                break;
            } else {
                temp.push(arr[i]);
            }
        }
        
        // if no pair found, array remains same
        if (changed) arr = temp;
    }
    
    return arr;
}


// Driver code
let arr = [10, -5, -8, 2, -5];
let result = reducePairs(arr);

for (let i = 0; i < result.length; i++) {
    console.log(result[i] + " ");
}

[Expected Approach] Using Stack - O(n) Time and O(n) Space

The idea is to traverse the array and use a stack to store elements. For each element, resolve collisions with the stack top whenever they have opposite signs, by removing the smaller absolute value or both if equal. Continue this process until no conflict remains, then push the current element. The stack finally contains the valid elements after handling all adjacent opposite sign interactions.


C++
#include <iostream>
#include <vector>
using namespace std;

vector<int> reducePairs(vector<int>& arr) {

    vector<int> s;

    // Traverse each element
    for (int element : arr) {

        // Process while there is a collision (opposite signs)
        while (!s.empty() && s.back() * element < 0) {
            
            int top = s.back();

            // Top has larger absolute value, keep top
            if (abs(top) > abs(element)) {
                element = top;
                s.pop_back();
            }
            
            // Current element has larger absolute value
            // keep current element
            else if (abs(top) < abs(element)) {
                s.pop_back();  
            }
                
            // Both have same absolute value, both removed
            else {
                s.pop_back(); 
                element = 0; 
                break;
            }
        }

        // If current element still exists, push into stack
        if (element != 0)
            s.push_back(element);
    }

    return s;
}

int main() {
    vector<int> arr = {10, -5, -8, 2, -5};  

    vector<int> result = reducePairs(arr);  

    for (int i = 0; i < result.size(); i++) {
        cout << result[i] << " ";
    }

    return 0;
}
Java
import java.util.ArrayList;

class GfG {
    static ArrayList<Integer> reducePairs(int[] arr) {
        ArrayList<Integer> s = new ArrayList<>();

        // Traverse each element
        for (int element : arr) {

            // Process while there is a collision (opposite signs)
            while (!s.isEmpty() && s.get(s.size() - 1) * element < 0) {
                int top = s.get(s.size() - 1);

                // Top has larger absolute value, keep top
                if (Math.abs(top) > Math.abs(element)) {
                    element = top;
                    s.remove(s.size() - 1);
                }

                // Current element has larger absolute value
                // keep current element
                else if (Math.abs(top) < Math.abs(element)) {
                    s.remove(s.size() - 1);
                }

                // Both have same absolute value, both removed
                else {
                    s.remove(s.size() - 1);
                    element = 0;
                    break;
                }
            }

            // If current element still exists, push into stack
            if (element != 0)
                s.add(element);
        }

        return s;
    }

    public static void main(String[] args) {
        int[] arr = {10, -5, -8, 2, -5};
        ArrayList<Integer> result = reducePairs(arr);

        for (int i = 0; i < result.size(); i++) {
            System.out.print(result.get(i) + " ");
        }
    }
}
Python
def reducePairs(arr):
    s = []

    # Traverse each element
    for element in arr:

        # Process while there is a collision (opposite signs)
        while s and s[-1] * element < 0:
            top = s[-1]

            # Top has larger absolute value, keep top
            if abs(top) > abs(element):
                element = top
                s.pop()
            
            # Current element has larger absolute value
            # keep current element
            elif abs(top) < abs(element):
                s.pop()
            
            # Both have same absolute value, both removed
            else:
                s.pop()
                element = 0
                break

        # If current element still exists, push into stack
        if element!= 0:
            s.append(element)

    return s

if __name__ == '__main__':
    arr = [10, -5, -8, 2, -5]
    result = reducePairs(arr)
    for i in result:
        print(i, end=' ')
C#
using System;
using System.Collections.Generic;

class GfG {
    static List<int> reducePairs(int[] arr)
    {
        List<int> s = new List<int>();

        // Traverse each element
        foreach(int elementVal in arr)
        {
            int element = elementVal;

            // Process while there is a collision (opposite
            // signs)
            while (s.Count > 0
                   && s[s.Count - 1] * element < 0) {
                int top = s[s.Count - 1];

                // Top has larger absolute value, keep top
                if (Math.Abs(top) > Math.Abs(element)) {
                    element = top;
                    s.RemoveAt(s.Count - 1);
                }

                // Current element has larger absolute value
                // keep current element
                else if (Math.Abs(top)
                         < Math.Abs(element)) {
                    s.RemoveAt(s.Count - 1);
                }

                // Both have same absolute value, both
                // removed
                else {
                    s.RemoveAt(s.Count - 1);
                    element = 0;
                    break;
                }
            }

            // If current element still exists, push into
            // stack
            if (element != 0)
                s.Add(element);
        }

        return s;
    }

    public static void Main()
    {
        int[] arr = { 10, -5, -8, 2, -5 };
        List<int> result = reducePairs(arr);

        foreach(int i in result) { Console.Write(i + " "); }
    }
}
JavaScript
function reducePairs(arr) {
    let s = [];

    // Traverse each element
    for (let element of arr) {

        // Process while there is a collision (opposite signs)
        while (s.length > 0 && s[s.length - 1] * element < 0) {
            let top = s[s.length - 1];

            // Top has larger absolute value, keep top
            if (Math.abs(top) > Math.abs(element)) {
                element = top;
                s.pop();
            }

            // Current element has larger absolute value
            // keep current element
            else if (Math.abs(top) < Math.abs(element)) {
                s.pop();
            }

            // Both have same absolute value, both removed
            else {
                s.pop();
                element = 0;
                break;
            }
        }

        // If current element still exists, push into stack
        if (element!= 0)
            s.push(element);
    }

    return s;
}

// Driver code
let arr = [10, -5, -8, 2, -5];
let result = reducePairs(arr);
for (let i = 0; i < result.length; i++) {
    console.log(result[i] + " ");
}

Output
10 
Comment