Three way partitioning of an Array without changing the relative ordering
Last Updated :
12 May, 2022
Given an array and a range [lowVal, highVal], partition the array around the range such that the array is divided into three parts.
- All elements smaller than lowVal come first.
- All elements in range lowVal to highVal come next.
- All elements greater than highVVal appear in the end.
- The relative ordering of numbers shouldn't be changed.

Examples:
Input: arr[] = {1, 14, 5, 20, 4, 2, 54, 20, 87, 98, 3, 1, 32}, lowVal = 14, highVal = 20
Output: arr[] = { 1 5 4 2 3 1 14 20 20 54 87 98 32 }
Input: arr[] = {1, 14, 5, 20, 4, 2, 54, 20, 87, 98, 3, 1, 32}, lowVal = 20, highVal = 20
Output: arr[] = { 1 14 5 4 2 3 1 20 20 54 87 98 32 }
Approach: This approach is based on using extra data structures to store the elements lesser than lowVal, in between lowVal and highVal, and elements greater than highVal. We will be using 3 queue for maintaining the original order of elements.
- Traverse the array one by one
- Insert the array elements into the respective queue one by one
- At the end,
- Pop out all the elements in queue 1 with elements lesser than lowVal
- Then Pop out all the elements in queue 2 with elements in between lowVal and highVal
- Then Pop out all the elements in queue 3 with elements greater than highVal.
Below is the implementation of the above approach:
C++
// C++ code to implement three way
// partitioning of an array without
// changing the relative ordering
#include <bits/stdc++.h>
using namespace std;
// Function to do three way partitioning
vector<int> pivotArray(vector<int>& nums, int lowVal,
int highVal)
{
// Declaring 3 queues
queue<int> before, same, after;
// Traverse the array elements one by one
for (int i = 0; i < nums.size(); i++) {
// If the element is
// less than pivot range
// insert it into queue before
if (nums[i] < lowVal)
before.push(nums[i]);
// Else If the element is
// in between pivot range
// insert it into queue same
else if (nums[i] > highVal)
after.push(nums[i]);
// Else If the element is
// less than pivot range
// insert it into queue after
else
same.push(nums[i]);
}
int k = 0;
// Now insert all elements
// in queue before and
// insert into final vector
while (before.size() > 0) {
nums[k++] = before.front();
before.pop();
}
// Now insert all elements
// in queue same and
// insert into final vector
while (same.size() > 0) {
nums[k++] = same.front();
same.pop();
}
// Now insert all elements
// in queue after and
// insert into final vector
while (after.size() > 0) {
nums[k++] = after.front();
after.pop();
}
// Return the final vector
return nums;
}
// Driver code
int main()
{
vector<int> arr
= { 1, 14, 5, 20, 4, 2, 54,
20, 87, 98, 3, 1, 32 };
int lowVal = 20, highVal = 20;
pivotArray(arr, lowVal, highVal);
for (int i = 0; i < arr.size(); i++) {
cout << arr[i] << " ";
}
return 0;
}
Java
// JAVA code to implement three way
// partitioning of an array without
// changing the relative ordering
import java.util.*;
class GFG {
// Function to do three way partitioning
public static int[] pivotArray(int[] nums, int lowVal,
int highVal)
{
// Declaring 3 queues
Queue<Integer> before = new LinkedList<>();
Queue<Integer> same = new LinkedList<>();
Queue<Integer> after = new LinkedList<>();
// Traverse the array elements one by one
for (int i = 0; i < nums.length; i++) {
// If the element is
// less than pivot range
// insert it into queue before
if (nums[i] < lowVal)
before.add(nums[i]);
// Else If the element is
// in between pivot range
// insert it into queue same
else if (nums[i] > highVal)
after.add(nums[i]);
// Else If the element is
// less than pivot range
// insert it into queue after
else
same.add(nums[i]);
}
int k = 0;
// Now insert all elements
// in queue before and
// insert into final vector
while (before.size() > 0) {
nums[k++] = before.poll();
}
// Now insert all elements
// in queue same and
// insert into final vector
while (same.size() > 0) {
nums[k++] = same.poll();
}
// Now insert all elements
// in queue after and
// insert into final vector
while (after.size() > 0) {
nums[k++] = after.poll();
}
// Return the final vector
return nums;
}
// Driver code
public static void main(String[] args)
{
int arr[] = new int[] { 1, 14, 5, 20, 4, 2, 54,
20, 87, 98, 3, 1, 32 };
int lowVal = 20, highVal = 20;
pivotArray(arr, lowVal, highVal);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
// This code is contributed by Taranpreet
Python3
# Python 3 code to implement three way
# partitioning of an array without
# changing the relative ordering
# Function to do three way partitioning
def pivotArray(nums, lowVal,
highVal):
# Declaring 3 queues
before = []
same = []
after = []
# Traverse the array elements one by one
for i in range(len(nums)):
# If the element is
# less than pivot range
# insert it into queue before
if (nums[i] < lowVal):
before.append(nums[i])
# Else If the element is
# in between pivot range
# insert it into queue same
elif (nums[i] > highVal):
after.append(nums[i])
# Else If the element is
# less than pivot range
# insert it into queue after
else:
same.append(nums[i])
k = 0
# Now insert all elements
# in queue before and
# insert into final vector
while (len(before) > 0):
nums[k] = before[0]
k += 1
before.pop(0)
# Now insert all elements
# in queue same and
# insert into final vector
while (len(same) > 0):
nums[k] = same[0]
same.pop(0)
k += 1
# Now insert all elements
# in queue after and
# insert into final vector
while (len(after) > 0):
nums[k] = after[0]
k += 1
after.pop(0)
# Return the final vector
return nums
# Driver code
if __name__ == "__main__":
arr = [1, 14, 5, 20, 4, 2, 54,
20, 87, 98, 3, 1, 32]
lowVal = 20
highVal = 20
pivotArray(arr, lowVal, highVal)
for i in range(len(arr)):
print(arr[i], end=" ")
# This code is contributed by ukasp.
C#
// C# code to implement three way
using System;
using System.Collections;
public class GFG{
// partitioning of an array without
// changing the relative ordering
// Function to do three way partitioning
static int[] pivotArray(int[] nums, int lowVal,
int highVal)
{
// Declaring 3 queues
Queue before = new Queue();
Queue same = new Queue();
Queue after = new Queue();
// Traverse the array elements one by one
for (int i = 0; i < nums.Length; i++) {
// If the element is
// less than pivot range
// insert it into queue before
if (nums[i] < lowVal)
before.Enqueue(nums[i]);
// Else If the element is
// in between pivot range
// insert it into queue same
else if (nums[i] > highVal)
after.Enqueue(nums[i]);
// Else If the element is
// less than pivot range
// insert it into queue after
else
same.Enqueue(nums[i]);
}
int k = 0;
// Now insert all elements
// in queue before and
// insert into final vector
while (before.Count > 0) {
nums[k++] = (int)before.Peek();
before.Dequeue();
}
// Now insert all elements
// in queue same and
// insert into final vector
while (same.Count > 0) {
nums[k++] = (int)same.Peek();
same.Dequeue();
}
// Now insert all elements
// in queue after and
// insert into final vector
while (after.Count > 0) {
nums[k++] = (int)after.Peek();
after.Dequeue();
}
// Return the final vector
return nums;
}
// Driver code
static public void Main (){
int [ ] arr
= { 1, 14, 5, 20, 4, 2, 54,
20, 87, 98, 3, 1, 32 };
int lowVal = 20, highVal = 20;
pivotArray(arr, lowVal, highVal);
for (int i = 0; i < arr.Length; i++) {
Console.Write(arr[i] + " ");
}
}
}
// This code is contributed by hrithikgarg03188.
JavaScript
<script>
// JavaScript code to implement three way
// partitioning of an array without
// changing the relative ordering
// Function to do three way partitioning
const pivotArray = (nums, lowVal, highVal) => {
// Declaring 3 queues
let before = [], same = [], after = [];
// Traverse the array elements one by one
for (let i = 0; i < nums.length; i++) {
// If the element is
// less than pivot range
// insert it into queue before
if (nums[i] < lowVal)
before.push(nums[i]);
// Else If the element is
// in between pivot range
// insert it into queue same
else if (nums[i] > highVal)
after.push(nums[i]);
// Else If the element is
// less than pivot range
// insert it into queue after
else
same.push(nums[i]);
}
let k = 0;
// Now insert all elements
// in queue before and
// insert into final vector
while (before.length > 0) {
nums[k++] = before[0];
before.shift();
}
// Now insert all elements
// in queue same and
// insert into final vector
while (same.length > 0) {
nums[k++] = same[0];
same.shift();
}
// Now insert all elements
// in queue after and
// insert into final vector
while (after.length > 0) {
nums[k++] = after[0];
after.shift();
}
// Return the final vector
return nums;
}
// Driver code
let arr = [1, 14, 5, 20, 4, 2, 54,
20, 87, 98, 3, 1, 32];
let lowVal = 20, highVal = 20;
pivotArray(arr, lowVal, highVal);
for (let i = 0; i < arr.length; i++) {
document.write(`${arr[i]} `);
}
// This code is contributed by rakeshsahni
</script>
Output1 14 5 4 2 3 1 20 20 54 87 98 32
Time Complexity: O(N), where N is the size of the array.
Auxiliary Space: O(N)
Similar Reads
Three way partitioning of an array around a given range Given an array and a range [lowVal, highVal], partition the array around the range such that array is divided in three parts. All elements smaller than lowVal come first. All elements in range lowVal to highVal come next. All elements greater than highVal appear in the end. The individual elements o
7 min read
Three way partitioning around an element Given an array arr[] of integers and a value pivot, the task is to partition the array around the pivot such that array is divided in three parts. All elements smaller than pivot come first. All elements equal to pivot come next. All elements greater than pivot appear in the end. The individual elem
14 min read
Number of times an array can be partitioned repetitively into two subarrays with equal sum Given an array arr[] of size N, the task is to find the number of times the array can be partitioned repetitively into two subarrays such that the sum of the elements of both the subarrays is the same. Examples: Input: arr[] = { 2, 2, 2, 2 } Output: 3 Explanation: 1. Make the first partition after i
8 min read
Partition the given array in two parts to make the MEX of both parts same Given an array arr[] containing N integers where 0 ⤠A[ i ] ⤠N, the task is to divide the array into two equal parts such that the MEX of both the parts are the same, otherwise print -1. Note: The MEX (minimum excluded) of an array is the smallest non-negative integer that does not exist in the arr
9 min read
Partition the array into three equal sum segments Given an array of n integers, we have to partition the array into three segments such that all the segments have an equal sum. Segment sum is the sum of all the elements in the segment. Examples: Input : 1, 3, 6, 2, 7, 1, 2, 8 Output : [1, 3, 6], [2, 7, 1], [2, 8] Input : 7, 6, 1, 7 Output : [7], [6
12 min read