Given an array arr[] of length n + m, where the first n elements are already sorted, sort the whole array.
Examples:
Input: arr[] = [1, 3, 6, 19, 11, 16], m = 3
Output: [1, 3, 6, 11, 16, 19]
Explanation: Sorting last 3 elements [19, 11, 16] and merging with first 3 sorted elements [1, 3, 6] gives [1, 3, 6, 11, 16, 19].Input: arr[] = [1, 3, 5, 2, 6, 4], m = 3
Output: [1, 2, 3, 4, 5, 6]
Explanation: Sorting the last 3 elements [2,6,4] and merging with the first 3 sorted elements [1, 3, 5] gives [1, 2, 3, 4, 5, 6].
Table of Content
[Naive Approach] Sorting Entire Array - O((n+m) log(n+m)) Time and O(1) Space
The simplest idea is to ignore the fact that first n elements are already sorted and just sort the entire array using any standard sorting algorithm. This is simple but does not take advantage of the pre-sorted first n elements.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
static void sortLastM(vector<int> &arr, int m)
{
// Sort the entire array
sort(arr.begin(), arr.end());
}
int main()
{
vector<int> arr = {1, 3, 6, 19, 11, 16};
int m = 3;
sortLastM(arr, m);
for (int i = 0; i < (int)arr.size(); i++)
{
if (i != 0)
cout << " ";
cout << arr[i];
}
cout << endl;
return 0;
}
import java.util.Arrays;
class GFG {
static void sortLastM(int[] arr, int m) {
// Sort the entire array
Arrays.sort(arr);
}
public static void main(String[] args) {
int[] arr = {1, 3, 6, 19, 11, 16};
int m = 3;
sortLastM(arr, m);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
if (i != 0) sb.append(" ");
sb.append(arr[i]);
}
System.out.println(sb);
}
}
def sortLastM(arr, m):
# Sort the entire array
arr.sort()
if __name__ == "__main__":
arr = [1, 3, 6, 19, 11, 16]
m = 3
sortLastM(arr, m)
print(' '.join(map(str, arr)))
using System;
class GFG {
static void sortLastM(int[] arr, int m) {
// Sort the entire array
Array.Sort(arr);
}
static void Main() {
int[] arr = {1, 3, 6, 19, 11, 16};
int m = 3;
sortLastM(arr, m);
Console.WriteLine(string.Join(" ", arr));
}
}
function sortLastM(arr, m) {
// Sort the entire array
arr.sort((a, b) => a - b);
}
// Driver code
let arr = [1, 3, 6, 19, 11, 16];
let m = 3;
sortLastM(arr, m);
console.log(arr.join(' '));
Output
1 3 6 11 16 19
[Expected Approach] Sort Last M and Merge - O(n + m log m) Time and O(m) Space
The idea is to take advantage of the fact that first n elements are already sorted. Sort only the last m elements and then merge them with the first n sorted elements using two pointers from right to left - this avoids any extra O(n) space by filling the result from the end of the array.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
static void sortLastM(vector<int> &arr, int m)
{
// Calculate n from array size and m
int n = arr.size() - m;
// Sort last m elements and store in temp
vector<int> temp(arr.begin() + n, arr.end());
sort(temp.begin(), temp.end());
// Fill from right using two pointers
int i = n - 1, j = m - 1, k = arr.size() - 1;
while (i >= 0 && j >= 0)
arr[k--] = arr[i] >= temp[j] ? arr[i--] : temp[j--];
while (j >= 0)
arr[k--] = temp[j--];
}
int main()
{
vector<int> arr = {1, 3, 6, 19, 11, 16};
int m = 3;
sortLastM(arr, m);
for (int i = 0; i < (int)arr.size(); i++)
{
if (i != 0)
cout << " ";
cout << arr[i];
}
cout << endl;
return 0;
}
import java.util.Arrays;
class GFG {
static void sortLastM(int[] arr, int m) {
// Calculate n from array size and m
int n = arr.length - m;
// Sort last m elements and store in temp
int[] temp = Arrays.copyOfRange(arr, n, arr.length);
Arrays.sort(temp);
// Fill from right using two pointers
int i = n - 1, j = m - 1, k = arr.length - 1;
while (i >= 0 && j >= 0)
arr[k--] = arr[i] >= temp[j] ? arr[i--] : temp[j--];
while (j >= 0)
arr[k--] = temp[j--];
}
public static void main(String[] args) {
int[] arr = {1, 3, 6, 19, 11, 16};
int m = 3;
sortLastM(arr, m);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
if (i != 0) sb.append(" ");
sb.append(arr[i]);
}
System.out.println(sb);
}
}
def sortLastM(arr, m):
# Calculate n from array size and m
n = len(arr) - m
# Sort last m elements and store in temp
temp = sorted(arr[n:])
# Fill from right using two pointers
i, j, k = n - 1, m - 1, len(arr) - 1
while i >= 0 and j >= 0:
if arr[i] >= temp[j]:
arr[k] = arr[i]
i -= 1
else:
arr[k] = temp[j]
j -= 1
k -= 1
while j >= 0:
arr[k] = temp[j]
j -= 1
k -= 1
if __name__ == "__main__":
arr = [1, 3, 6, 19, 11, 16]
m = 3
sortLastM(arr, m)
print(' '.join(map(str, arr)))
using System;
class GFG {
static void sortLastM(int[] arr, int m) {
// Calculate n from array size and m
int n = arr.Length - m;
// Sort last m elements and store in temp
int[] temp = new int[m];
Array.Copy(arr, n, temp, 0, m);
Array.Sort(temp);
// Fill from right using two pointers
int i = n - 1, j = m - 1, k = arr.Length - 1;
while (i >= 0 && j >= 0)
arr[k--] = arr[i] >= temp[j] ? arr[i--] : temp[j--];
while (j >= 0)
arr[k--] = temp[j--];
}
static void Main() {
int[] arr = {1, 3, 6, 19, 11, 16};
int m = 3;
sortLastM(arr, m);
Console.WriteLine(string.Join(" ", arr));
}
}
function sortLastM(arr, m) {
// Calculate n from array size and m
let n = arr.length - m;
// Sort last m elements and store in temp
let temp = arr.slice(n).sort((a, b) => a - b);
// Fill from right using two pointers
let i = n - 1, j = m - 1, k = arr.length - 1;
while (i >= 0 && j >= 0)
arr[k--] = arr[i] >= temp[j] ? arr[i--] : temp[j--];
while (j >= 0)
arr[k--] = temp[j--];
}
// Driver code
let arr = [1, 3, 6, 19, 11, 16];
let m = 3;
sortLastM(arr, m);
console.log(arr.join(' '));
Output
1 3 6 11 16 19