Variety-1
Problem Statement:
There’s an array ‘A’ of size ‘N’ with an equal number of positive and negative elements. Without altering the relative order of positive and negative elements, you must return an array of alternately positive and negative values.
Note: Start the array with positive elements.
Examples:
Example 1: Input: arr[] = {1,2,-4,-5}, N = 4 Output: 1 -4 2 -5 Explanation: Positive elements = 1,2 Negative elements = -4,-5 To maintain relative ordering, 1 must occur before 2, and -4 must occur before -5. Example 2: Input: arr[] = {1,2,-3,-1,-2,-3}, N = 6 Output: 1 -3 2 -1 3 -2 Explanation: Positive elements = 1,2,3 Negative elements = -3,-1,-2 To maintain relative ordering, 1 must occur before 2, and 2 must occur before 3. Also, -3 should come before -1, and -1 should come before -2.
Solution
Disclaimer: Don’t jump directly to the solution, try it out yourself first.
Note: In case any image/dry run is not clear please refer to the video attached at the bottom.
Brute Force Method
Approach:
- In this simple approach, since the number of positive and negative elements are the same, we put positives into an array called “pos” and negatives into an array called “neg”.
- After segregating each of the positive and negative elements, we start putting them alternatively back into array A.
- Since the array must begin with a positive number and the start index is 0, so all the positive numbers would be placed at even indices (2*i) and negatives at the odd indices (2*i+1), where i is the index of the pos or neg array while traversing them simultaneously.
- This approach uses O(N+N/2) of running time due to multiple traversals which we’ll try to optimize in the optimized approach given below.

For a better understanding of intuition, please watch the video at the bottom of my page.
Code:
C++ Code
#include<bits/stdc++.h>
using namespace std;
vector<int> RearrangebySign(vector<int>A, int n){
// Define 2 vectors, one for storing positive
// and other for negative elements of the array.
vector<int> pos;
vector<int> neg;
// Segregate the array into positives and negatives.
for(int i=0;i<n;i++){
if(A[i]>0) pos.push_back(A[i]);
else neg.push_back(A[i]);
}
// Positives on even indices, negatives on odd.
for(int i=0;i<n/2;i++){
A[2*i] = pos[i];
A[2*i+1] = neg[i];
}
return A;
}
int main() {
// Array Initialisation.
int n = 4;
vector<int> A {1,2,-4,-5};
vector<int> ans = RearrangebySign(A,n);
for (int i = 0; i < ans.size(); i++) {
cout << ans[i] << " ";
}
return 0;
}
Output :
1 -4 2 -5
Time Complexity: O(N+N/2) { O(N) for traversing the array once for segregating positives and negatives and another O(N/2) for adding those elements alternatively to the array, where N = size of the array A}.
Space Complexity: O(N/2 + N/2) = O(N) { N/2 space required for each of the positive and negative element arrays, where N = size of the array A}.
Java Code
import java.util.*;
class TUF{
public static int[] RearrangebySign(int[] A, int n){
// Define 2 vectors, one for storing positive
// and other for negative elements of the array.
ArrayList<Integer> pos=new ArrayList<>();
ArrayList<Integer> neg=new ArrayList<>();
// Segregate the array into positives and negatives.
for(int i=0;i<n;i++){
if(A[i]>0) pos.add(A[i]);
else neg.add(A[i]);
}
// Positives on even indices, negatives on odd.
for(int i=0;i<n/2;i++){
A[2*i] = pos.get(i);
A[2*i+1] = neg.get(i);
}
return A;
}
public static void main(String args[])
{
// Array Initialisation.
int n = 4;
int A[]= {1,2,-4,-5};
int[]ans= RearrangebySign(A,n);
for (int i = 0; i < n; i++) {
System.out.print(ans[i]+" ");
}
}
}
Output :
1 -4 2 -5
Time Complexity: O(N+N/2) { O(N) for traversing the array once for segregating positives and negatives and another O(N/2) for adding those elements alternatively to the array, where N = size of the array A}.
Space Complexity: O(N/2 + N/2) = O(N) { N/2 space required for each of the positive and negative element arrays, where N = size of the array A}.
Python Code
def rearrange_by_sign(A):
# Define 2 lists, one for storing positive and other for negative elements of the array.
pos = []
neg = []
# Segregate the array into positives and negatives.
for i in range(len(A)):
if A[i] > 0:
pos.append(A[i])
else:
neg.append(A[i])
# Positives on even indices, negatives on odd.
for i in range(len(pos)):
A[2 * i] = pos[i]
for i in range(len(neg)):
A[2 * i + 1] = neg[i]
return A
# Array Initialisation.
A = [1, 2, -4, -5]
ans = rearrange_by_sign(A)
for i in range(len(ans)):
print(ans[i], end=" ")
Output :
1 -4 2 -5
Time Complexity: O(N+N/2) { O(N) for traversing the array once for segregating positives and negatives and another O(N/2) for adding those elements alternatively to the array, where N = size of the array A}.
Space Complexity: O(N/2 + N/2) = O(N) { N/2 space required for each of the positive and negative element arrays, where N = size of the array A}.
Javascript Code
// Define a function to rearrange an array of integers by sign.
function RearrangebySign(A, n) {
// Define 2 arrays, one for storing positive
// and other for negative elements of the array.
let pos = [];
let neg = [];
// Segregate the array into positives and negatives.
for (let i = 0; i < n; i++) {
if (A[i] > 0) {
pos.push(A[i]);
} else {
neg.push(A[i]);
}
}
// Positives on even indices, negatives on odd.
for (let i = 0; i < n / 2; i++) {
A[2 * i] = pos[i];
A[2 * i + 1] = neg[i];
}
return A;
}
// Define an array and call the RearrangebySign function.
let A = [1, 2, -4, -5];
let n = A.length;
let ans = RearrangebySign(A, n);
// Print the result.
console.log(ans.join(" "));
Output :
1 -4 2 -5
Time Complexity: O(N+N/2) { O(N) for traversing the array once for segregating positives and negatives and another O(N/2) for adding those elements alternatively to the array, where N = size of the array A}.
Space Complexity: O(N/2 + N/2) = O(N) { N/2 space required for each of the positive and negative element arrays, where N = size of the array A}.
Optimal Method
Approach:
- In this optimal approach, we will try to solve the problem in a single pass and try to arrange the array elements in the correct order in that pass only.
- We know that the resultant array must start from a positive element so we initialize the positive index as 0 and negative index as 1 and start traversing the array such that whenever we see the first positive element, it occupies the space at 0 and then posIndex increases by 2 (alternate places).
- Similarly, when we encounter the first negative element, it occupies the position at index 1, and then each time we find a negative number, we put it on the negIndex and it increments by 2.
- When both the negIndex and posIndex exceed the size of the array, we see that the whole array is now rearranged alternatively according to the sign.
For a better understanding of intuition, please watch the video at the bottom of my page.
Code:
C++ Code
#include<bits/stdc++.h>
using namespace std;
vector<int> RearrangebySign(vector<int>A){
int n = A.size();
// Define array for storing the ans separately.
vector<int> ans(n,0);
// positive elements start from 0 and negative from 1.
int posIndex = 0, negIndex = 1;
for(int i = 0;i<n;i++){
// Fill negative elements in odd indices and inc by 2.
if(A[i]<0){
ans[negIndex] = A[i];
negIndex+=2;
}
// Fill positive elements in even indices and inc by 2.
else{
ans[posIndex] = A[i];
posIndex+=2;
}
}
return ans;
}
int main() {
// Array Initialisation.
vector<int> A = {1,2,-4,-5};
vector<int> ans = RearrangebySign(A);
for (int i = 0; i < ans.size(); i++) {
cout << ans[i] << " ";
}
return 0;
}
Output :
1 -4 2 -5
Time Complexity: O(N) { O(N) for traversing the array once and substituting positives and negatives simultaneously using pointers, where N = size of the array A}.
Space Complexity: O(N) { Extra Space used to store the rearranged elements separately in an array, where N = size of array A}.
Java Code
import java.util.*;
public class Main {
public static void main(String[] args) {
// Array Initialization.
ArrayList<Integer> A = new ArrayList<>(Arrays.asList(1, 2, -4, -5));
ArrayList<Integer> ans = RearrangebySign(A);
for (int i = 0; i < ans.size(); i++) {
System.out.print(ans.get(i) + " ");
}
}
public static ArrayList<Integer> RearrangebySign(ArrayList<Integer> A) {
int n = A.size();
// Define array for storing the ans separately.
ArrayList<Integer> ans = new ArrayList<>(Collections.nCopies(n, 0));
// positive elements start from 0 and negative from 1.
int posIndex = 0, negIndex = 1;
for (int i = 0; i < n; i++) {
// Fill negative elements in odd indices and inc by 2.
if (A.get(i) < 0) {
ans.set(negIndex, A.get(i));
negIndex += 2;
}
// Fill positive elements in even indices and inc by 2.
else {
ans.set(posIndex, A.get(i));
posIndex += 2;
}
}
return ans;
}
}
Output :
1 -4 2 -5
Time Complexity: O(N) { O(N) for traversing the array once and substituting positives and negatives simultaneously using pointers, where N = size of the array A}.
Space Complexity: O(N) { Extra Space used to store the rearranged elements separately in an array, where N = size of array A}.
Python Code
from typing import List
def RearrangebySign(A: List[int]) -> List[int]:
n = len(A)
# Define array for storing the ans separately.
ans = [0] * n
# positive elements start from 0 and negative from 1.
posIndex, negIndex = 0, 1
for i in range(n):
# Fill negative elements in odd indices and inc by 2.
if A[i] < 0:
ans[negIndex] = A[i]
negIndex += 2
# Fill positive elements in even indices and inc by 2.
else:
ans[posIndex] = A[i]
posIndex += 2
return ans
# Test the function
A = [1,2,-4,-5]
ans = RearrangebySign(A)
print(ans)
Output :
1 -4 2 -5
Time Complexity: O(N) { O(N) for traversing the array once and substituting positives and negatives simultaneously using pointers, where N = size of the array A}.
Space Complexity: O(N) { Extra Space used to store the rearranged elements separately in an array, where N = size of array A}.
Javascript Code
// Define a function to rearrange an array of integers by sign.
function RearrangebySign(A) {
let n = A.length;
// Define an array for storing the answer separately.
let ans = new Array(n).fill(0);
// Positive elements start from 0 and negative from 1.
let posIndex = 0, negIndex = 1;
for (let i = 0; i < n; i++) {
// Fill negative elements in odd indices and increment by 2.
if (A[i] < 0) {
ans[negIndex] = A[i];
negIndex += 2;
}
// Fill positive elements in even indices and increment by 2.
else {
ans[posIndex] = A[i];
posIndex += 2;
}
}
return ans;
}
// Define an array and call the RearrangebySign function.
let A = [1, 2, -4, -5];
let ans = RearrangebySign(A);
// Print the result.
console.log(ans.join(" "));
Output :
1 -4 2 -5
Time Complexity: O(N) { O(N) for traversing the array once and substituting positives and negatives simultaneously using pointers, where N = size of the array A}.
Space Complexity: O(N) { Extra Space used to store the rearranged elements separately in an array, where N = size of array A}.
Variety-2
Problem Statement:
There’s an array ‘A’ of size ‘N’ with positive and negative elements (not necessarily equal). Without altering the relative order of positive and negative elements, you must return an array of alternately positive and negative values. The leftover elements should be placed at the very end in the same order as in array A.
Note: Start the array with positive elements.
Examples:
Example 1: Input: arr[] = {1,2,-4,-5,3,4}, N = 6 Output: 1 -4 2 -5 3 4 Explanation: Positive elements = 1,2 Negative elements = -4,-5 To maintain relative ordering, 1 must occur before 2, and -4 must occur before -5. Leftover positive elements are 3 and 4 which are then placed at the end of the array. Example 2: Input: arr[] = {1,2,-3,-1,-2,-3}, N = 6 Output: 1 -3 2 -1 3 -2 Explanation: Positive elements = 1,2 Negative elements = -3,-1,-2,-4 To maintain relative ordering, 1 must occur before 2. Also, -3 should come before -1, and -1 should come before -2. After alternate ordering, -2 and -4 are left, which would be placed at the end of the ans array.
Solution
Disclaimer: Don’t jump directly to the solution, try it out yourself first.
Note: In case any image/dry run is not clear please refer to the video attached at the bottom.
Intuition:
In this variety, the number of positive and negative numbers shall not necessarily be equal to each other in the given array. So, there can be two cases possible: either the positive elements exceed the negatives or the negatives exceed the positives. So, instead of using the optimal solution discussed for the variety-1 above, we’ll fall back to the brute force solution where we create separate arrays for storing positives and negatives and then put them back into the array alternatively. The remaining negative or positive elements are added to the array at last.
Approach:
- In this problem, first, we create a neg array and a pos array for storing all the negative and positive elements of array A separately.
- Now, similar to the Brute force approach for variety-1, we start putting elements of pos and neg array alternatively back into array A.
- Since the array must begin with a positive number and the start index is 0, so all the positive numbers would be placed at even indices (2*i) and negatives at the odd indices (2*i+1), where i is the index of the pos or neg array while traversing them simultaneously.
- After all the elements are added to the index where positives were equal to the negatives, we now put all the remaining elements ( whether positive or negative) at the last of the array by running a single loop from pos.size() to neg.size() {if positives < negatives} or neg.size() to pos.size() {if negatives < positives}.
For a better understanding of intuition, please watch the video at the bottom of my page.
Code:
C++ Code
#include<bits/stdc++.h>
using namespace std;
vector<int> RearrangebySign(vector<int>A, int n){
// Define 2 vectors, one for storing positive
// and other for negative elements of the array.
vector<int> pos;
vector<int> neg;
// Segregate the array into positives and negatives.
for(int i=0;i<n;i++){
if(A[i]>0) pos.push_back(A[i]);
else neg.push_back(A[i]);
}
// If positives are lesser than the negatives.
if(pos.size() < neg.size()){
// First, fill array alternatively till the point
// where positives and negatives ar equal in number.
for(int i=0;i<pos.size();i++){
A[2*i] = pos[i];
A[2*i+1] = neg[i];
}
// Fill the remaining negatives at the end of the array.
int index = pos.size()*2;
for(int i = pos.size();i<neg.size();i++){
A[index] = neg[i];
index++;
}
}
// If negatives are lesser than the positives.
else{
// First, fill array alternatively till the point
// where positives and negatives ar equal in number.
for(int i=0;i<neg.size();i++){
A[2*i] = pos[i];
A[2*i+1] = neg[i];
}
// Fill the remaining positives at the end of the array.
int index = neg.size()*2;
for(int i = neg.size();i<pos.size();i++){
A[index] = pos[i];
index++;
}
}
return A;
}
int main() {
// Array Initialisation.
int n = 6;
vector<int> A {1,2,-4,-5,3,4};
vector<int> ans = RearrangebySign(A,n);
for (int i = 0; i < ans.size(); i++) {
cout << ans[i] << " ";
}
return 0;
}
Output :
1 -4 2 -5 3 4
Time Complexity: O(2*N) { The worst case complexity is O(2*N) which is a combination of O(N) of traversing the array to segregate into neg and pos array and O(N) for adding the elements alternatively to the main array}.
Explanation: The second O(N) is a combination of O(min(pos, neg)) + O(leftover elements). There can be two cases: when only positive or only negative elements are present, O(min(pos, neg)) + O(leftover) = O(0) + O(N), and when equal no. of positive and negative elements are present, O(min(pos, neg)) + O(leftover) = O(N/2) + O(0). So, from these two cases, we can say the worst-case time complexity is O(N) for the second part, and by adding the first part we get the total complexity of O(2*N).
Space Complexity: O(N/2 + N/2) = O(N) { N/2 space required for each of the positive and negative element arrays, where N = size of the array A}.
Java Code
import java.util.*;
public class Main {
public static void main(String[] args) {
// Array Initialization
int n = 6;
ArrayList<Integer> A = new ArrayList<>(Arrays.asList(1, 2, -4, -5, 3, 4));
ArrayList<Integer> ans = RearrangebySign(A, n);
for (int i = 0; i < ans.size(); i++) {
System.out.print(ans.get(i) + " ");
}
}
public static ArrayList<Integer> RearrangebySign(ArrayList<Integer> A, int n) {
// Define 2 ArrayLists, one for storing positive
// and other for negative elements of the array.
ArrayList<Integer> pos = new ArrayList<>();
ArrayList<Integer> neg = new ArrayList<>();
// Segregate the array into positives and negatives.
for (int i = 0; i < n; i++) {
if (A.get(i) > 0)
pos.add(A.get(i));
else
neg.add(A.get(i));
}
// If positives are lesser than the negatives.
if (pos.size() < neg.size()) {
// First, fill array alternatively till the point
// where positives and negatives are equal in number.
for (int i = 0; i < pos.size(); i++) {
A.set(2 * i, pos.get(i));
A.set(2 * i + 1, neg.get(i));
}
// Fill the remaining negatives at the end of the array.
int index = pos.size() * 2;
for (int i = pos.size(); i < neg.size(); i++) {
A.set(index, neg.get(i));
index++;
}
}
// If negatives are lesser than the positives.
else {
// First, fill array alternatively till the point
// where positives and negatives are equal in number.
for (int i = 0; i < neg.size(); i++) {
A.set(2 * i, pos.get(i));
A.set(2 * i + 1, neg.get(i));
}
// Fill the remaining positives at the end of the array.
int index = neg.size() * 2;
for (int i = neg.size(); i < pos.size(); i++) {
A.set(index, pos.get(i));
index++;
}
}
return A;
}
}
Output :
1 -4 2 -5 3 4
Time Complexity: O(2*N) { The worst case complexity is O(2*N) which is a combination of O(N) of traversing the array to segregate into neg and pos array and O(N) for adding the elements alternatively to the main array}.
Explanation: The second O(N) is a combination of O(min(pos, neg)) + O(leftover elements). There can be two cases: when only positive or only negative elements are present, O(min(pos, neg)) + O(leftover) = O(0) + O(N), and when equal no. of positive and negative elements are present, O(min(pos, neg)) + O(leftover) = O(N/2) + O(0). So, from these two cases, we can say the worst-case time complexity is O(N) for the second part, and by adding the first part we get the total complexity of O(2*N).
Space Complexity: O(N/2 + N/2) = O(N) { N/2 space required for each of the positive and negative element arrays, where N = size of the array A}.
Python Code
def RearrangebySign(A, n):
# Define 2 lists, one for storing positive
# and other for negative elements of the array.
pos = []
neg = []
# Segregate the array into positives and negatives.
for i in range(n):
if A[i] > 0:
pos.append(A[i])
else:
neg.append(A[i])
# If positives are lesser than the negatives.
if len(pos) < len(neg):
# First, fill array alternatively till the point
# where positives and negatives are equal in number.
for i in range(len(pos)):
A[2*i] = pos[i]
A[2*i+1] = neg[i]
# Fill the remaining negatives at the end of the array.
index = len(pos)*2
for i in range(len(neg)-len(pos)):
A[index] = neg[len(pos)+i]
index += 1
# If negatives are lesser than the positives.
else:
# First, fill array alternatively till the point
# where positives and negatives are equal in number.
for i in range(len(neg)):
A[2*i] = pos[i]
A[2*i+1] = neg[i]
# Fill the remaining positives at the end of the array.
index = len(neg)*2
for i in range(len(pos)-len(neg)):
A[index] = pos[len(neg)+i]
index += 1
return A
# Array initialization
n = 6
A = [1, 2, -4, -5, 3, 4]
ans = RearrangebySign(A, n)
for i in range(len(ans)):
print(ans[i], end=" ")
Output :
1 -4 2 -5 3 4
Time Complexity: O(2*N) { The worst case complexity is O(2*N) which is a combination of O(N) of traversing the array to segregate into neg and pos array and O(N) for adding the elements alternatively to the main array}.
Explanation: The second O(N) is a combination of O(min(pos, neg)) + O(leftover elements). There can be two cases: when only positive or only negative elements are present, O(min(pos, neg)) + O(leftover) = O(0) + O(N), and when equal no. of positive and negative elements are present, O(min(pos, neg)) + O(leftover) = O(N/2) + O(0). So, from these two cases, we can say the worst-case time complexity is O(N) for the second part, and by adding the first part we get the total complexity of O(2*N).
Space Complexity: O(N/2 + N/2) = O(N) { N/2 space required for each of the positive and negative element arrays, where N = size of the array A}.
Javascript Code
function RearrangebySign(A) {
let n = A.length;
// Define 2 arrays, one for storing positive
// and other for negative elements of the array.
let pos = [];
let neg = [];
// Segregate the array into positives and negatives.
for(let i=0;i<n;i++){
if(A[i]>0) pos.push(A[i]);
else neg.push(A[i]);
}
// If positives are lesser than the negatives.
if(pos.length < neg.length){
// First, fill array alternatively till the point
// where positives and negatives are equal in number.
for(let i=0;i<pos.length;i++){
A[2*i] = pos[i];
A[2*i+1] = neg[i];
}
// Fill the remaining negatives at the end of the array.
let index = pos.length*2;
for(let i = pos.length;i<neg.length;i++){
A[index] = neg[i];
index++;
}
}
// If negatives are lesser than the positives.
else{
// First, fill array alternatively till the point
// where positives and negatives are equal in number.
for(let i=0;i<neg.length;i++){
A[2*i] = pos[i];
A[2*i+1] = neg[i];
}
// Fill the remaining positives at the end of the array.
let index = neg.length*2;
for(let i = neg.length;i<pos.length;i++){
A[index] = pos[i];
index++;
}
}
return A;
}
// Array Initialisation.
let A = [1,2,-4,-5,3,4];
let ans = RearrangebySign(A);
for (let i = 0; i < ans.length; i++) {
console.log(ans[i]);
}
Output :
1 -4 2 -5 3 4
Time Complexity: O(2*N) { The worst case complexity is O(2*N) which is a combination of O(N) of traversing the array to segregate into neg and pos array and O(N) for adding the elements alternatively to the main array}.
Explanation: The second O(N) is a combination of O(min(pos, neg)) + O(leftover elements). There can be two cases: when only positive or only negative elements are present, O(min(pos, neg)) + O(leftover) = O(0) + O(N), and when equal no. of positive and negative elements are present, O(min(pos, neg)) + O(leftover) = O(N/2) + O(0). So, from these two cases, we can say the worst-case time complexity is O(N) for the second part, and by adding the first part we get the total complexity of O(2*N).
Space Complexity: O(N/2 + N/2) = O(N) { N/2 space required for each of the positive and negative element arrays, where N = size of the array A}.
Special thanks to Priyanshi Goel for contributing to this article on takeUforward. If you also wish to share your knowledge with the takeUforward fam, please check out this article