📌  相关文章
📜  在不改变相对顺序的情况下对数组进行三向分区

📅  最后修改于: 2022-05-13 01:56:15.998000             🧑  作者: Mango

在不改变相对顺序的情况下对数组进行三向分区

给定一个数组和一个范围 [ lowVal , highVal ],围绕范围对数组进行分区,使数组分为三个部分。

  • 所有小于lowVal的元素都排在第一位。
  • 接下来是从lowValhighVal范围内的所有元素。
  • 所有大于highVVal的元素都出现在最后。
  • 不应更改数字的相对顺序。

例子:

方法:此方法基于使用额外的数据结构来存储小于 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)