不改变相对顺序的数组三向分区


在本文中,我们将对包含N个整数的数组进行三向分区。

该方法是使用三个队列。每个队列都将用于存储一部分元素。之后,我们可以从各自的队列中获取每一部分的元素,而不会改变元素的相对顺序。

问题陈述

给定一个包含N个整数的数组和一个范围[LOW, HIGH],我们需要将数组分成三个部分,使得:

  • 小于LOW的元素排在最前面

  • 大于LOW且小于HIGH的元素排在中间。

  • 大于HIGH的元素排在最后。

  • 元素的相对顺序保持不变

示例

输入

arr = {3,1,5,10,3,7,2,5,6,8}, LOW = 3, HIGH = 7

输出

1 2 3 5 3 7 5 6 10 8

解释

这里,小于3的元素首先出现,然后是3到7之间的元素,最后是大于7的元素。元素的相对顺序保持不变。

输入

arr = {10,9,8,7,6,5,4,3,2,1}, LOW = 5, HIGH = 8

输出

4 3 2 1 8 7 6 5 10 9

解释

这里,小于5的元素首先出现,然后是5到8之间的元素,最后是大于8的元素。元素的相对顺序保持不变。

输入

arr = {4,3,3,5,6,3,100,321,45,54,5,6,1,2,3}, LOW = 5, HIGH = 10

输出

4 3 3 3 1 2 3 5 6 5 6 100 321 45 54

解释

这里,小于5的元素首先出现,然后是5到7之间的元素,最后是大于7的元素。元素的相对顺序保持不变。

方法1

在这种方法中,我们将使用三个队列数据结构来存储三个部分的元素,即小于LOW的、LOW和HIGH之间的、大于HIGH的。这也会保持元素的原始顺序。

算法

  • 步骤1 - 遍历数组元素。

  • 步骤2 - 将元素插入到相应的队列中。

  • 步骤2.1 - 如果元素小于LOW,则将其插入队列1。

  • 步骤2.2 - 如果元素在LOW和HIGH之间,则将其插入队列2。

  • 步骤2.3 - 如果元素大于HIGH,则将其插入队列3。

  • 步骤3.1 - 从队列1中弹出所有元素并将其添加到结果数组中。

  • 步骤3.2 - 从队列2中弹出所有元素并将其添加到结果数组中。

  • 步骤3.3 - 从队列3中弹出所有元素并将其添加到结果数组中。

  • 步骤4 - 返回结果数组。

示例

#include<iostream>
#include<vector>
#include<queue>
using namespace std;
vector<int> ThreeWayPartition(vector<int> &arr,int LOW,int HIGH){
   queue<int> q1,q2,q3;
   vector<int> ans;
   for(int i=0;i<arr.size();i++){
      if(arr[i]<LOW)q1.push(arr[i]);
      else if(arr[i]>=LOW && arr[i]<=HIGH)q2.push(arr[i]);
      else q3.push(arr[i]);
   }
   while(!q1.empty()){
      ans.push_back(q1.front());
      q1.pop();
   }
   while(!q2.empty()){
      ans.push_back(q2.front());
      q2.pop();
   }
   while(!q3.empty()){
      ans.push_back(q3.front());
      q3.pop();
   }
   return ans;
}
int main(){
   vector<int> arr = {4,3,3,5,6,3,100,321,45,54,5,6,1,2,3};
   int LOW = 5 , HIGH=10;
   vector<int> ans = ThreeWayPartition(arr,LOW,HIGH);
   for(int i=0;i<ans.size();i++)cout<<ans[i]<<" ";
   cout<<'\n';
}

输出

4 3 3 3 1 2 3 5 6 5 6 100 321 45 54 

时间复杂度 - O(N),其中N是数组的大小

空间复杂度 - O(N),用于存储数组的元素

更新于:2023年11月1日

浏览量:143

启动你的职业生涯

完成课程获得认证

开始
广告