Given an array arr[] of positive integers. The task is to sort them so that the first part of the array contains odd numbers sorted in descending order, and the rest of the portion contains even numbers sorted in ascending order.
Examples:
Input: arr[] = [1, 2, 3, 5, 4, 7, 10]
Output: [7, 5, 3, 1, 2, 4, 10]
Explanation: 7, 5, 3, 1 are odds in descending order and 2, 4, 10 are evens in ascending order.Input: arr[] = [0, 4, 5, 3, 7, 2, 1]
Output: [7, 5, 3, 1, 0, 2, 4]
Explanation: 7, 5, 3, 1 are odds in descending order and 0, 2, 4 are evens in ascending order.Input: arr[] = [6, 9, 2, 8, 3, 7]
Output: [9, 7, 3, 2, 6, 8]
Explanation: 9, 7, 3 are odds in descending order and 2, 6, 8 are evens in ascending order.
Table of Content
- [Naive Approach] Using Two Auxiliary Arrays - O(n*log(n)) Time and O(n) Space
- [Expected Approach - 1] Using Partition Method - O(n*log(n)) Time and O(1) Space
- [Expected Approach - 2] Using Negative Multiplication - O(n*log(n)) Time and O(1) Space
- [Expected Approach - 3] Using Custom Comparator - O(n*log(n)) Time and O(1) Space
[Naive Approach] Using Two Auxiliary Arrays - O(n*log(n)) Time and O(n) Space
The idea is to first separate all odd and even numbers into two different arrays. Then, we sort the odd numbers in descending order and the even numbers in ascending order. Finally, we reconstruct the original array by placing all sorted odd numbers first, followed by the sorted even numbers.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// Function to sort array as per the condition
void sortIt(vector<int>& arr) {
vector<int> odds;
vector<int> evens;
// Separate the elements into odds and evens
for (int i = 0; i < arr.size(); i++) {
if (arr[i] % 2 == 1) {
odds.push_back(arr[i]);
}
else {
evens.push_back(arr[i]);
}
}
// Sort odds in descending order
sort(odds.begin(), odds.end(), greater<int>());
// Sort evens in ascending order
sort(evens.begin(), evens.end());
// Merge both back into the original array
int idx = 0;
for (int i = 0; i < odds.size(); i++) {
arr[idx++] = odds[i];
}
for (int i = 0; i < evens.size(); i++) {
arr[idx++] = evens[i];
}
}
int main() {
vector<int> arr = {1, 2, 3, 5, 4, 7, 10};
sortIt(arr);
for (int x : arr) {
cout << x << " ";
}
return 0;
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class GfG {
// Function to sort array as per the condition
static void sortIt(int[] arr) {
List<Integer> odds = new ArrayList<>();
List<Integer> evens = new ArrayList<>();
// Separate the elements into odds and evens
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 == 1) {
odds.add(arr[i]);
} else {
evens.add(arr[i]);
}
}
// Sort odds in descending order
Collections.sort(odds, Collections.reverseOrder());
// Sort evens in ascending order
Collections.sort(evens);
// Merge both back into the original array
int idx = 0;
for (int i = 0; i < odds.size(); i++) {
arr[idx++] = odds.get(i);
}
for (int i = 0; i < evens.size(); i++) {
arr[idx++] = evens.get(i);
}
}
public static void main(String[] args) {
int[] arr = {1, 2, 3, 5, 4, 7, 10};
sortIt(arr);
for (int x : arr) {
System.out.print(x + " ");
}
}
}
def sortIt(arr):
odds = []
evens = []
# Separate the elements into odds and evens
for i in range(len(arr)):
if arr[i] % 2 == 1:
odds.append(arr[i])
else:
evens.append(arr[i])
# Sort odds in descending order
odds.sort(reverse=True)
# Sort evens in ascending order
evens.sort()
# Merge both back into the original array
idx = 0
for i in range(len(odds)):
arr[idx] = odds[i]
idx += 1
for i in range(len(evens)):
arr[idx] = evens[i]
idx += 1
if __name__ == "__main__":
arr = [1, 2, 3, 5, 4, 7, 10]
sortIt(arr)
for x in arr:
print(x, end=" ")
using System;
using System.Collections.Generic;
class GfG {
// Function to sort array as per the condition
static void sortIt(int[] arr) {
List<int> odds = new List<int>();
List<int> evens = new List<int>();
// Separate the elements into odds and evens
for (int i = 0; i < arr.Length; i++) {
if (arr[i] % 2 == 1) {
odds.Add(arr[i]);
} else {
evens.Add(arr[i]);
}
}
// Sort odds in descending order
odds.Sort((a, b) => b - a);
// Sort evens in ascending order
evens.Sort();
// Merge both back into the original array
int idx = 0;
for (int i = 0; i < odds.Count; i++) {
arr[idx++] = odds[i];
}
for (int i = 0; i < evens.Count; i++) {
arr[idx++] = evens[i];
}
}
static void Main() {
int[] arr = {1, 2, 3, 5, 4, 7, 10};
sortIt(arr);
foreach (int x in arr) {
Console.Write(x + " ");
}
}
}
function sortIt(arr) {
let odds = [];
let evens = [];
// Separate the elements into odds and evens
for (let i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 1) {
odds.push(arr[i]);
} else {
evens.push(arr[i]);
}
}
// Sort odds in descending order
odds.sort((a, b) => b - a);
// Sort evens in ascending order
evens.sort((a, b) => a - b);
// Merge both back into the original array
let idx = 0;
for (let i = 0; i < odds.length; i++) {
arr[idx++] = odds[i];
}
for (let i = 0; i < evens.length; i++) {
arr[idx++] = evens[i];
}
}
// Driver Code
let arr = [1, 2, 3, 5, 4, 7, 10] ;
sortIt(arr);
for (let x of arr) {
process.stdout.write(x + " ");
}
Output
7 5 3 1 2 4 10
[Expected Approach - 1] Using Partition Method - O(n*log(n)) Time and O(1) Space
The idea is to partition the array such that all odd numbers are placed before the even numbers. Once partitioned, we can independently sort the odd and even parts: odds in descending and evens in ascending order. This avoids using extra space and gives an efficient in-place solution.
Steps to implement the above idea:
- Declare an integer left = 0 to track the position for placing odd numbers during partition.
- Traverse the array and swap current element with arr[left] if it is an odd number.
- Increment left after every successful odd placement to maintain correct boundary between odds and evens.
- After traversal, the array is partitioned with all odds on the left and evens on the right.
- Apply descending sort on the subarray from index 0 to left - 1 for odd numbers.
- Apply ascending sort on the subarray from index left to n - 1 for the even numbers.
- Finally, return the array.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// Function to sort array as per the condition
void sortIt(vector<int>& arr) {
int n = arr.size();
int left = 0;
// Partition: Move all odds to the front
for (int i = 0; i < n; i++) {
if (arr[i] % 2 == 1) {
swap(arr[i], arr[left]);
left++;
}
}
// Sort odds in descending order
sort(arr.begin(), arr.begin() + left, greater<int>());
// Sort evens in ascending order
sort(arr.begin() + left, arr.end());
}
int main() {
vector<int> arr = {1, 2, 3, 5, 4, 7, 10};
sortIt(arr);
for (int x : arr) {
cout << x << " ";
}
return 0;
}
import java.util.Arrays;
class GfG {
// Function to sort array as per the condition
static void sortIt(int[] arr) {
int n = arr.length;
int left = 0;
// Partition: Move all odds to the front
for (int i = 0; i < n; i++) {
if (arr[i] % 2 == 1) {
int temp = arr[i];
arr[i] = arr[left];
arr[left] = temp;
left++;
}
}
// Sort odds in descending order
Arrays.sort(arr, 0, left);
for (int i = 0; i < left / 2; i++) {
int temp = arr[i];
arr[i] = arr[left - 1 - i];
arr[left - 1 - i] = temp;
}
// Sort evens in ascending order
Arrays.sort(arr, left, n);
}
public static void main(String[] args) {
int[] arr = {1, 2, 3, 5, 4, 7, 10};
sortIt(arr);
for (int x : arr) {
System.out.print(x + " ");
}
}
}
def sortIt(arr):
n = len(arr)
left = 0
# Partition: Move all odds to the front
for i in range(n):
if arr[i] % 2 == 1:
arr[i], arr[left] = arr[left], arr[i]
left += 1
# Sort odds in descending order
arr[:left] = sorted(arr[:left], reverse=True)
# Sort evens in ascending order
arr[left:] = sorted(arr[left:])
if __name__ == "__main__":
arr = [1, 2, 3, 5, 4, 7, 10]
sortIt(arr)
for x in arr:
print(x, end=" ")
using System;
class GfG {
// Function to sort array as per the condition
public static void sortIt(int[] arr) {
int n = arr.Length;
int left = 0;
// Partition: Move all odds to the front
for (int i = 0; i < n; i++) {
if (arr[i] % 2 == 1) {
int temp = arr[i];
arr[i] = arr[left];
arr[left] = temp;
left++;
}
}
// Sort odds in descending order
Array.Sort(arr, 0, left);
Array.Reverse(arr, 0, left);
// Sort evens in ascending order
Array.Sort(arr, left, n - left);
}
public static void Main() {
int[] arr = {1, 2, 3, 5, 4, 7, 10};
sortIt(arr);
foreach (int x in arr) {
Console.Write(x + " ");
}
}
}
function sortIt(arr) {
let n = arr.length;
let left = 0;
// Partition: Move all odds to the front
for (let i = 0; i < n; i++) {
if (arr[i] % 2 === 1) {
let temp = arr[i];
arr[i] = arr[left];
arr[left] = temp;
left++;
}
}
// Sort odds in descending order
arr.slice(0, left)
.sort((a, b) => b - a)
.forEach((val, i) => arr[i] = val);
// Sort evens in ascending order
arr.slice(left)
.sort((a, b) => a - b)
.forEach((val, i) => arr[left + i] = val);
}
// Driver code
let arr = [1, 2, 3, 5, 4, 7, 10];
sortIt(arr);
for (let x of arr) {
process.stdout.write(x + " ");
}
Output
7 5 3 1 2 4 10
[Expected Approach - 2] Using Negative Multiplication - O(n*log(n)) Time and O(1) Space
The idea is to utilize the fact that negative odd numbers will be treated as smaller in ascending sort. So, we convert all odd elements to negative, making larger odd values more negative (e.g., 7 becomes -7). During sorting, these more negative values (i.e., originally bigger odds) are pushed further to the left, achieving descending order for odds. After sorting, we revert negative numbers back to positive, placing odds in descending order followed by evens in ascending order.
Note: This approach fails when the array already contains negative values, as it cannot distinguish between original and transformed negatives, leading to incorrect results.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// Function to sort array as per the condition
void sortIt(vector<int>& arr) {
// Make odd elements negative
for (int i = 0; i < arr.size(); i++) {
if (arr[i] % 2 == 1) {
arr[i] *= -1;
}
}
// Sort entire array
sort(arr.begin(), arr.end());
// Make negative elements (originally odds)
// positive again
for (int i = 0; i < arr.size(); i++) {
if (arr[i] < 0) {
arr[i] *= -1;
}
}
}
int main() {
vector<int> arr = {1, 2, 3, 5, 4, 7, 10};
sortIt(arr);
for (int x : arr) {
cout << x << " ";
}
return 0;
}
import java.util.Arrays;
class GfG {
// Function to sort array as per the condition
static void sortIt(int[] arr) {
// Make odd elements negative
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 == 1) {
arr[i] *= -1;
}
}
// Sort entire array
Arrays.sort(arr);
// Make negative elements (originally odds)
// positive again
for (int i = 0; i < arr.length; i++) {
if (arr[i] < 0) {
arr[i] *= -1;
}
}
}
public static void main(String[] args) {
int[] arr = {1, 2, 3, 5, 4, 7, 10};
sortIt(arr);
for (int x : arr) {
System.out.print(x + " ");
}
}
}
def sortIt(arr):
# Make odd elements negative
for i in range(len(arr)):
if arr[i] % 2 == 1:
arr[i] *= -1
# Sort entire array
arr.sort()
# Make negative elements (originally odds)
# positive again
for i in range(len(arr)):
if arr[i] < 0:
arr[i] *= -1
if __name__ == "__main__":
arr = [1, 2, 3, 5, 4, 7, 10]
sortIt(arr)
for x in arr:
print(x, end=" ")
using System;
class GfG {
// Function to sort array as per the condition
public static void sortIt(int[] arr) {
// Make odd elements negative
for (int i = 0; i < arr.Length; i++) {
if (arr[i] % 2 == 1) {
arr[i] *= -1;
}
}
// Sort entire array
Array.Sort(arr);
// Make negative elements (originally odds)
// positive again
for (int i = 0; i < arr.Length; i++) {
if (arr[i] < 0) {
arr[i] *= -1;
}
}
}
public static void Main() {
int[] arr = {1, 2, 3, 5, 4, 7, 10};
sortIt(arr);
foreach (int x in arr) {
Console.Write(x + " ");
}
}
}
function sortIt(arr) {
// Make odd elements negative
for (let i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 1) {
arr[i] *= -1;
}
}
// Sort entire array
arr.sort((a, b) => a - b);
// Make negative elements (originally odds)
// positive again
for (let i = 0; i < arr.length; i++) {
if (arr[i] < 0) {
arr[i] *= -1;
}
}
}
// Driver code
let arr = [1, 2, 3, 5, 4, 7, 10];
sortIt(arr);
for (let x of arr) {
process.stdout.write(x + " ");
}
Output
7 5 3 1 2 4 10
[Expected Approach - 3] Using Custom Comparator - O(n*log(n)) Time and O(1) Space
The idea is to leverage the inbuilt sort function with a custom comparator to sort the array according to the desired condition. The logic for the comparator is based on how two elements compare under three distinct cases:
- If both elements are even, they should be arranged in ascending order, so the smaller even number comes first.
- If both elements are odd, they should be arranged in descending order, meaning the larger odd number should appear earlier.
- If one element is odd and the other is even, the odd number must come before the even number to maintain the required order.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// Custom compare function
bool compare(int a, int b) {
// When both are even: sort in ascending order
if (a % 2 == 0 && b % 2 == 0) {
return a < b;
}
// When both are odd: sort in descending order
if (a % 2 == 1 && b % 2 == 1) {
return a > b;
}
// If one is odd and one is even: odd comes first
return a % 2 == 1;
}
// Function to sort array as per the condition
void sortIt(vector<int>& arr) {
// Sort using the custom comparator
sort(arr.begin(), arr.end(), compare);
}
int main() {
vector<int> arr = {1, 2, 3, 5, 4, 7, 10};
sortIt(arr);
for (int x : arr) {
cout << x << " ";
}
return 0;
}
import java.util.Arrays;
import java.util.Comparator;
class GfG {
// Function to sort array as per the condition
public static void sortIt(Integer[] arr) {
// Sort using the custom comparator
Arrays.sort(arr, new Comparator<Integer>() {
public int compare(Integer a, Integer b) {
// When both are even: sort in ascending order
if (a % 2 == 0 && b % 2 == 0) {
return a - b;
}
// When both are odd: sort in descending order
if (a % 2 == 1 && b % 2 == 1) {
return b - a;
}
// If one is odd and one is even: odd comes first
return (a % 2 == 1) ? -1 : 1;
}
});
}
// Driver code
public static void main(String[] args) {
Integer[] arr = {1, 2, 3, 5, 4, 7, 10};
sortIt(arr);
for (int x : arr) {
System.out.print(x + " ");
}
}
}
from functools import cmp_to_key
# Custom compare function
def compare(a, b):
# When both are even: sort in ascending order
if a % 2 == 0 and b % 2 == 0:
return a - b
# When both are odd: sort in descending order
if a % 2 == 1 and b % 2 == 1:
return b - a
# If one is odd and one is even: odd comes first
return -1 if a % 2 == 1 else 1
# Function to sort array as per the condition
def sortIt(arr):
# Sort using the custom comparator
arr.sort(key=cmp_to_key(compare))
if __name__ == "__main__":
arr = [1, 2, 3, 5, 4, 7, 10]
sortIt(arr)
for x in arr:
print(x, end=" ")
using System;
using System.Collections.Generic;
class GfG {
// Custom compare function
class CustomComparer : IComparer<int> {
public int Compare(int a, int b) {
// When both are even: sort in ascending order
if (a % 2 == 0 && b % 2 == 0) {
return a - b;
}
// When both are odd: sort in descending order
if (a % 2 == 1 && b % 2 == 1) {
return b - a;
}
// If one is odd and one is even: odd comes first
return (a % 2 == 1) ? -1 : 1;
}
}
// Function to sort array as per the condition
public static void sortIt(int[] arr) {
// Sort using the custom comparator
Array.Sort(arr, new CustomComparer());
}
public static void Main() {
int[] arr = {1, 2, 3, 5, 4, 7, 10};
sortIt(arr);
foreach (int x in arr) {
Console.Write(x + " ");
}
}
}
function compare(a, b) {
// When both are even: sort in ascending order
if (a % 2 === 0 && b % 2 === 0) {
return a - b;
}
// When both are odd: sort in descending order
if (a % 2 === 1 && b % 2 === 1) {
return b - a;
}
// If one is odd and one is even: odd comes first
return (a % 2 === 1) ? -1 : 1;
}
// Function to sort array as per the condition
function sortIt(arr) {
// Sort using the custom comparator
arr.sort(compare);
}
// Driver code
let arr = [1, 2, 3, 5, 4, 7, 10];
sortIt(arr);
for (let i = 0; i < arr.length; i++) {
process.stdout.write(arr[i] + " ");
}
Output
7 5 3 1 2 4 10