给定K增减数组arr [] ,任务是对给定数组进行排序。如果元素重复增加到某个索引,然后减少,然后又增加,总共K次,则数组被称为K递增-递减。下图显示了一个4增减数组。
例子:
Input: arr[] = {57, 131, 493, 294, 221, 339, 418, 458, 442, 190}
Output: 57 131 190 221 294 339 418 442 458 493
Input: arr[] = {1, 2, 3, 4, 3, 2, 1}
Output: 1 1 2 2 3 3 4
方法:蛮力方法是在不利用k增加-减少属性的情况下对数组进行排序。此方法的时间复杂度为O(n logn),其中n是数组的长度。
如果k显着小于n,则可以找到一种更好的方法,并且时间复杂度更低。例如,如果k = 2,则输入数组由两个子数组组成,一个子数组增加,另一个子数组减少。反转第二个子数组会产生两个排序的数组,然后合并结果,可以在O(n)时间内完成。概括而言,我们可以首先反转每个递减子数组的顺序。例如,在上图中,该数组可以分解为四个分类的数组,分别为{57,131,493},{221,294},{339,418,458}和{190,442}。现在,可以使用最小堆技术合并这些排序的数组。
下面是上述方法的实现:
// C++ implementation of the approach
#include
using namespace std;
// A pair of pairs, first element is going to
// store value, second element index of array
// and third element index in the array
typedef pair > ppi;
// This function takes an array of arrays as an
// argument and all arrays are assumed to be
// sorted
// It merges them together and returns the
// final sorted output
vector mergeKArrays(vector > arr)
{
vector output;
// Create a min heap with k heap nodes
// Every heap node has first element of an array
priority_queue, greater > pq;
for (int i = 0; i < arr.size(); i++)
pq.push({ arr[i][0], { i, 0 } });
// Now one by one get the minimum element
// from min heap and replace it with next
// element of its array
while (pq.empty() == false) {
ppi curr = pq.top();
pq.pop();
// i ==> Array Number
// j ==> Index in the array number
int i = curr.second.first;
int j = curr.second.second;
output.push_back(curr.first);
// The next element belongs to same array as
// current
if (j + 1 < arr[i].size())
pq.push({ arr[i][j + 1], { i, j + 1 } });
}
return output;
}
// Function to sort the alternating
// increasing-decreasing array
vector SortKIncDec(const vector& A)
{
// Decompose the array into a
// set of sorted arrays
vector > sorted_subarrays;
typedef enum { INCREASING,
DECREASING } SubarrayType;
SubarrayType subarray_type = INCREASING;
int start_idx = 0;
for (int i = 0; i <= A.size(); i++) {
// If the current subarrays ends here
if (i == A.size()
|| (A[i - 1] < A[i]
&& subarray_type == DECREASING)
|| (A[i - 1] >= A[i]
&& subarray_type == INCREASING)) {
// If the subarray is increasing
// then add from the start
if (subarray_type == INCREASING) {
sorted_subarrays.emplace_back(A.cbegin() + start_idx,
A.cbegin() + i);
}
// If the subarray is decreasing
// then add from the end
else {
sorted_subarrays.emplace_back(A.crbegin()
+ A.size() - i,
A.crbegin()
+ A.size()
- start_idx);
}
start_idx = i;
subarray_type = (subarray_type == INCREASING
? DECREASING
: INCREASING);
}
}
// Merge the k sorted arrays`
return mergeKArrays(sorted_subarrays);
}
// Driver code
int main()
{
vector arr = { 57, 131, 493, 294, 221,
339, 418, 458, 442, 190 };
// Get the sorted array
vector ans = SortKIncDec(arr);
// Print the sorted array
for (int i = 0; i < ans.size(); i++)
cout << ans[i] << " ";
return 0;
}
57 131 190 221 294 339 418 442 458 493
时间复杂度: O(n * logk),其中n是数组的长度。
如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。