给定一个包含 n 个元素的数组,其中每个元素与其目标位置的距离至多 k,设计一个算法,在 O(n log k) 时间内进行排序。例如,让我们考虑 k 是 2,排序数组中索引为 7 的元素可以位于给定数组中的索引 5、6、7、8、9。可以假设k < n。
例子:
Input: arr[] = {6, 5, 3, 2, 8, 10, 9},
k = 3
Output: arr[] = {2, 3, 5, 6, 8, 9, 10}
Input: arr[] = {10, 9, 8, 7, 4, 70, 60, 50},
k = 4
Output: arr[] = {4, 7, 8, 9, 10, 50, 60, 70}
简单方法:基本的解决方案是使用任何标准排序算法对数组进行排序。
CPP14
// A STL based C++ program to
// sort a nearly sorted array.
#include
using namespace std;
// Given an array of size n,
// where every element
// is k away from its target
// position, sorts the
// array in O(n Log n) time.
int sortK(int arr[], int n, int k)
{
// Sort the array using
// inbuilt function
sort(arr, arr + n);
}
// An utility function to print
// array elements
void printArray(
int arr[], int size)
{
for (int i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
}
// Driver program to test
// above functions
int main()
{
int k = 3;
int arr[] = { 2, 6, 3, 12, 56, 8 };
int n = sizeof(arr) / sizeof(arr[0]);
sortK(arr, n, k);
cout << "Following is sorted array\n";
printArray(arr, n);
return 0;
}
Java
// A STL based Java program to
// sort a nearly sorted array.
import java.util.*;
public class GFG
{
// Given an array of size n,
// where every element
// is k away from its target
// position, sorts the
// array in O(n Log n) time.
static void sortK(int[] arr, int n, int k)
{
// Sort the array using
// inbuilt function
Arrays.sort(arr);
}
// An utility function to print
// array elements
static void printArray(
int[] arr, int size)
{
for (int i = 0; i < size; i++)
System.out.print(arr[i] + " ");
System.out.println();
}
// Driver code
public static void main(String[] args)
{
int k = 3;
int[] arr = { 2, 6, 3, 12, 56, 8 };
int n = arr.length;
sortK(arr, n, k);
System.out.println("Following is sorted array");
printArray(arr, n);
}
}
// This code is contributed by divyesh072019.
Python3
# A STL based Java program to
# sort a nearly sorted array.
# Given an array of size n,
# where every element
# is k away from its target
# position, sorts the
# array in O(n Log n) time.
def sortK(arr, n, k):
# Sort the array using
# inbuilt function
arr.sort()
# An utility function to print
# array elements
def printArray(arr, size):
for i in range(size):
print(arr[i], end = " ")
print()
# Driver code
k = 3
arr = [ 2, 6, 3, 12, 56, 8]
n = len(arr)
sortK(arr, n, k)
print("Following is sorted array")
printArray(arr, n)
# This code is contributed by avanitrachhadiya2155
C#
// A STL based C# program to
// sort a nearly sorted array.
using System;
class GFG
{
// Given an array of size n,
// where every element
// is k away from its target
// position, sorts the
// array in O(n Log n) time.
static void sortK(int[] arr, int n, int k)
{
// Sort the array using
// inbuilt function
Array.Sort(arr);
}
// An utility function to print
// array elements
static void printArray(
int[] arr, int size)
{
for (int i = 0; i < size; i++)
Console.Write(arr[i] + " ");
Console.WriteLine();
}
// Driver code
static void Main()
{
int k = 3;
int[] arr = { 2, 6, 3, 12, 56, 8 };
int n = arr.Length;
sortK(arr, n, k);
Console.WriteLine("Following is sorted array");
printArray(arr, n);
}
}
// This code is contributed by divyeshrabadiya07.
Javascript
CPP
// A STL based C++ program to sort
// a nearly sorted array.
#include
using namespace std;
// Given an array of size n,
// where every element
// is k away from its target
// position, sorts the
// array in O(nLogk) time.
int sortK(int arr[], int n, int k)
{
// Insert first k+1 items in a
// priority queue (or min heap)
// (A O(k) operation)
priority_queue,
greater >
pq(arr, arr + k + 1);
// i is index for remaining
// elements in arr[] and index
// is target index of for
// current minimum element in
// Min Heapm 'hp'.
int index = 0;
for (int i = k + 1; i < n; i++) {
arr[index++] = pq.top();
pq.pop();
pq.push(arr[i]);
}
while (pq.empty() == false) {
arr[index++] = pq.top();
pq.pop();
}
}
// A utility function to print
// array elements
void printArray(int arr[], int size)
{
for (int i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
}
// Driver program to test above functions
int main()
{
int k = 3;
int arr[] = { 2, 6, 3, 12, 56, 8 };
int n = sizeof(arr) / sizeof(arr[0]);
sortK(arr, n, k);
cout << "Following is sorted arrayn";
printArray(arr, n);
return 0;
}
输出:
Following is sorted arrayn2 3 6 8 12 56
复杂度分析:
- 时间复杂度: O(n log n),其中 n 是数组的大小。
排序算法需要 log n 时间。由于数组的大小为 n,因此整个程序需要 O(n log n) 时间。 - 空间复杂度: O(1)。
因为不需要额外的空间。
有效的解决方案:滑动窗口技术。
方法:更好的解决方案是使用优先级队列(或堆数据结构)。使用滑动窗口技术将窗口的连续 k 个元素保持在堆中。然后删除顶部元素(最小元素)并用它替换窗口的第一个元素。
由于每个元素最多相隔 k 距离,因此在窗口中保留 k 个连续元素,同时用从 i 到 (i+k) 的最小元素替换第 i 个元素就足够了(前 i-1 个元素已排序)。
算法:
- 构建一个包含前 (k+1) 个元素的优先级队列 pq。
- 初始化索引 = 0(对于结果数组)。
- 对从 k+1 到 n-1 的元素执行以下操作。
- 从 pq 弹出一个项目并将其放在索引处,增加索引。
- 将 arr[i] 推送到 pq。
- 虽然 pq 不为空,
从 pq 弹出一个项目并将其放在索引处,增加索引。
我们已经讨论了对近似排序(或 K 排序)数组进行排序中的一个简单实现。在这篇文章中,完成了一个基于 STL 的实现。
CPP
// A STL based C++ program to sort
// a nearly sorted array.
#include
using namespace std;
// Given an array of size n,
// where every element
// is k away from its target
// position, sorts the
// array in O(nLogk) time.
int sortK(int arr[], int n, int k)
{
// Insert first k+1 items in a
// priority queue (or min heap)
// (A O(k) operation)
priority_queue,
greater >
pq(arr, arr + k + 1);
// i is index for remaining
// elements in arr[] and index
// is target index of for
// current minimum element in
// Min Heapm 'hp'.
int index = 0;
for (int i = k + 1; i < n; i++) {
arr[index++] = pq.top();
pq.pop();
pq.push(arr[i]);
}
while (pq.empty() == false) {
arr[index++] = pq.top();
pq.pop();
}
}
// A utility function to print
// array elements
void printArray(int arr[], int size)
{
for (int i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
}
// Driver program to test above functions
int main()
{
int k = 3;
int arr[] = { 2, 6, 3, 12, 56, 8 };
int n = sizeof(arr) / sizeof(arr[0]);
sortK(arr, n, k);
cout << "Following is sorted arrayn";
printArray(arr, n);
return 0;
}
输出:
Following is sorted arrayn2 3 6 8 12 56
复杂度分析:
- 时间复杂度: O(n Log k)。
对于每个元素,它都被推入优先级队列,插入和删除需要 O(log k) 时间,因为优先级队列中有 k 个元素。 - 辅助空间: O(k)。
要在优先级队列中存储 k 个元素,需要 O(k) 空间。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。