💡 This approach leverages the k-sorted property by maintaining a min-heap of size k+1 to efficiently extract the next smallest element, improving time complexity.
Intuition
Since any element is at most k positions away from its sorted position, the smallest element in the current window of size k+1 must be in that window. Using a min-heap of size k+1 allows extracting the smallest element in O(log k) time.
Algorithm
- Create a min-heap and insert the first k+1 elements.
- For each remaining element in the array, extract the smallest element from the heap and add the next element from the array to the heap.
- After processing all elements, extract all remaining elements from the heap.
- Return the collected elements as the sorted array.
💡 This algorithm slides a window of size k+1 over the array, maintaining the smallest elements in a heap for efficient extraction.
import heapq
def sort_k_sorted_array(arr, k):
heap = arr[:k+1]
heapq.heapify(heap)
result = []
for i in range(k+1, len(arr)):
smallest = heapq.heappop(heap)
result.append(smallest)
heapq.heappush(heap, arr[i])
while heap:
result.append(heapq.heappop(heap))
return result
# Driver code
if __name__ == '__main__':
arr = [3, 2, 6, 5, 4]
k = 2
print(sort_k_sorted_array(arr, k))
Line Notes
import heapqImports Python's heapq module for min-heap operations
heap = arr[:k+1]Initializes heap with first k+1 elements, the window size
heapq.heapify(heap)Transforms list into a valid min-heap
for i in range(k+1, len(arr))Iterates over remaining elements beyond initial window
smallest = heapq.heappop(heap)Extracts smallest element from heap to append to result
heapq.heappush(heap, arr[i])Adds next element from array into heap maintaining size
while heap:Extracts remaining elements after main loop finishes
import java.util.*;
public class Main {
public static int[] sortKSortedArray(int[] arr, int k) {
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
int n = arr.length;
int[] result = new int[n];
int index = 0;
for (int i = 0; i <= k && i < n; i++) {
minHeap.add(arr[i]);
}
for (int i = k + 1; i < n; i++) {
result[index++] = minHeap.poll();
minHeap.add(arr[i]);
}
while (!minHeap.isEmpty()) {
result[index++] = minHeap.poll();
}
return result;
}
public static void main(String[] args) {
int[] arr = {3, 2, 6, 5, 4};
int k = 2;
int[] sorted = sortKSortedArray(arr, k);
System.out.println(Arrays.toString(sorted));
}
}
Line Notes
PriorityQueue<Integer> minHeap = new PriorityQueue<>();Creates a min-heap using Java's PriorityQueue
int n = arr.length;Stores array length for boundary checks
for (int i = 0; i <= k && i < n; i++) {Adds first k+1 elements to heap, handling array length
result[index++] = minHeap.poll();Extracts smallest element from heap to result array
minHeap.add(arr[i]);Adds next element from array to heap maintaining size
while (!minHeap.isEmpty()) {Extracts remaining elements after main loop
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
vector<int> sortKSortedArray(vector<int>& arr, int k) {
priority_queue<int, vector<int>, greater<int>> minHeap;
vector<int> result;
int n = arr.size();
for (int i = 0; i <= k && i < n; i++) {
minHeap.push(arr[i]);
}
for (int i = k + 1; i < n; i++) {
result.push_back(minHeap.top());
minHeap.pop();
minHeap.push(arr[i]);
}
while (!minHeap.empty()) {
result.push_back(minHeap.top());
minHeap.pop();
}
return result;
}
int main() {
vector<int> arr = {3, 2, 6, 5, 4};
int k = 2;
vector<int> sorted = sortKSortedArray(arr, k);
for (int num : sorted) cout << num << " ";
cout << endl;
return 0;
}
Line Notes
priority_queue<int, vector<int>, greater<int>> minHeap;Defines a min-heap using priority_queue with greater comparator
for (int i = 0; i <= k && i < n; i++) {Pushes first k+1 elements into min-heap
result.push_back(minHeap.top());Extracts smallest element from heap to result
minHeap.push(arr[i]);Adds next element from array to heap
while (!minHeap.empty()) {Extracts remaining elements after main loop
function sortKSortedArray(arr, k) {
const minHeap = [];
const result = [];
function heapPush(val) {
minHeap.push(val);
let i = minHeap.length - 1;
while (i > 0) {
let parent = Math.floor((i - 1) / 2);
if (minHeap[parent] <= minHeap[i]) break;
[minHeap[parent], minHeap[i]] = [minHeap[i], minHeap[parent]];
i = parent;
}
}
function heapPop() {
const top = minHeap[0];
const end = minHeap.pop();
if (minHeap.length > 0) {
minHeap[0] = end;
let i = 0;
while (true) {
let left = 2 * i + 1;
let right = 2 * i + 2;
let smallest = i;
if (left < minHeap.length && minHeap[left] < minHeap[smallest]) smallest = left;
if (right < minHeap.length && minHeap[right] < minHeap[smallest]) smallest = right;
if (smallest === i) break;
[minHeap[i], minHeap[smallest]] = [minHeap[smallest], minHeap[i]];
i = smallest;
}
}
return top;
}
for (let i = 0; i <= k && i < arr.length; i++) {
heapPush(arr[i]);
}
for (let i = k + 1; i < arr.length; i++) {
result.push(heapPop());
heapPush(arr[i]);
}
while (minHeap.length > 0) {
result.push(heapPop());
}
return result;
}
// Driver code
const arr = [3, 2, 6, 5, 4];
const k = 2;
console.log(sortKSortedArray(arr, k));
Line Notes
const minHeap = [];Initializes empty array to implement min-heap
function heapPush(val) {Defines function to insert element maintaining heap property
function heapPop() {Defines function to extract smallest element maintaining heap property
for (let i = 0; i <= k && i < arr.length; i++) {Pushes first k+1 elements into heap
result.push(heapPop());Extracts smallest element to result array
Building and maintaining a min-heap of size k+1 leads to O(n log k) time, which is efficient when k << n.
💡 For n=100000 and k=10, this means about 1 million operations, much faster than full sort.
Interview Verdict: Accepted and efficient for typical interview constraints
This approach is optimal for this problem and expected in interviews.