在不改变相对顺序的情况下对数组进行三向分区
给定一个数组和一个范围 [ lowVal , highVal ],围绕范围对数组进行分区,使数组分为三个部分。
- 所有小于lowVal的元素都排在第一位。
- 接下来是从lowVal到highVal范围内的所有元素。
- 所有大于highVVal的元素都出现在最后。
- 不应更改数字的相对顺序。
例子:
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 }
方法:此方法基于使用额外的数据结构来存储小于 lowVal、介于 lowVal 和 highVal 之间的元素以及大于 highVal 的元素。我们将使用 3 个队列来维护元素的原始顺序。
- 一个一个地遍历数组
- 将数组元素一一插入到各自的队列中
- 在末尾,
- 弹出队列 1 中元素小于 lowVal 的所有元素
- 然后弹出队列 2 中所有元素在 lowVal 和 highVal 之间的元素
- 然后弹出队列 3 中元素大于 highVal 的所有元素。
下面是上述方法的实现:
C++
// C++ code to implement three way
// partitioning of an array without
// changing the relative ordering
#include
using namespace std;
// Function to do three way partitioning
vector pivotArray(vector& nums, int lowVal,
int highVal)
{
// Declaring 3 queues
queue 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 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 before = new LinkedList<>();
Queue same = new LinkedList<>();
Queue 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
输出
1 14 5 4 2 3 1 20 20 54 87 98 32
时间复杂度: O(N),其中 N 是数组的大小。
辅助空间: O(N)