Given a big list of dates in ’20s, how to efficiently sort the list.
Example:
Input:
Date arr[] = {{20, 1, 2014},
{25, 3, 2010},
{ 3, 12, 2000},
{18, 11, 2001},
{19, 4, 2015},
{ 9, 7, 2005}}
Output:
Date arr[] = {{ 3, 12, 2000},
{18, 11, 2001},
{ 9, 7, 2005},
{25, 3, 2010},
{20, 1, 2014},
{19, 4, 2015}}
A Simple Solution is to use an O(N log N) algorithm like Merge Sort and a custom comparator. But we can sort the list in O(n) time using Radix Sort. In a typical Radix Sort implementation, we first sort by the last digit, then by second last digit, and so on. It is highly recommended to first go through the radix sort to understand this method. In this method we sort in the following order:
- First sort by day using counting sort
- Then sort by month using counting sort
- Finally, sort by year using counting sort
As the number of days, months, and years are fixed, all three steps take O(n) time. Therefore, the overall time complexity is O(n).
Below is the C++ implementation of the above idea:
C++
#include <bits/stdc++.h>
using namespace std;
int getMax( int arr[][3], int n, int q)
{
int maxi = INT_MIN;
for ( int i=0;i<n;i++){
maxi = max(maxi,arr[i][q]);
}
return maxi;
}
void sortDatesUtil( int arr[][3],
int n, int q)
{
int maxi = getMax(arr,n,q);
int p = 1;
while (maxi>0){
int cnt[10]={0};
for ( int i=0;i<n;i++)
{
cnt[(arr[i][q]/p)%10]++;
}
for ( int i=1;i<10;i++)
{
cnt[i]+=cnt[i-1];
}
int ans[n][3];
for ( int i=n-1;i>=0;i--)
{
int lastDigit = (arr[i][q]/p)%10;
for ( int j=0;j<3;j++)
{
ans[cnt[lastDigit]-1][j]
=arr[i][j];
}
cnt[lastDigit]--;
}
for ( int i=0;i<n;i++)
{
for ( int j=0;j<3;j++)
{
arr[i][j] = ans[i][j];
}
}
p*=10;
maxi/=10;
}
}
void sortDates( int dates[][3], int n)
{
sortDatesUtil(dates, n, 0);
sortDatesUtil(dates, n, 1);
sortDatesUtil(dates, n, 2);
}
void printArr( int arr[][3], int n)
{
for ( int i=0;i<6;i++)
{
for ( int j=0;j<3;j++)
{
cout<<arr[i][j]<< " " ;
}
cout<<endl;
}
}
int main()
{
int dates[][3] = {{20, 1, 2014},
{25, 3, 2010},
{ 3, 12, 2000},
{18, 11, 2000},
{19, 4, 2015},
{ 9, 7, 2005}};
int n = sizeof (dates)/ sizeof (dates[0]);
sortDates(dates,n);
cout<< "\nSorted Dates\n" ;
printArr(dates,n);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int getMax( int arr[][], int n, int q)
{
int maxi = Integer.MIN_VALUE;
for ( int i = 0 ; i < n; i++)
{
maxi = Math.max(maxi, arr[i][q]);
}
return maxi;
}
static void sortDatesUtil( int arr[][],
int n, int q)
{
int maxi = getMax(arr,n,q);
int p = 1 ;
while (maxi > 0 )
{
int []cnt = new int [ 10 ];
for ( int i = 0 ; i < n; i++)
{
cnt[(arr[i][q]/p) % 10 ]++;
}
for ( int i = 1 ; i < 10 ; i++)
{
cnt[i] += cnt[i - 1 ];
}
int [][]ans = new int [n][ 3 ];
for ( int i = n - 1 ; i >= 0 ; i--)
{
int lastDigit = (arr[i][q]/p) % 10 ;
for ( int j = 0 ; j < 3 ; j++)
{
ans[cnt[lastDigit]- 1 ][j]
=arr[i][j];
}
cnt[lastDigit]--;
}
for ( int i = 0 ; i < n; i++)
{
for ( int j = 0 ; j < 3 ; j++)
{
arr[i][j] = ans[i][j];
}
}
p *= 10 ;
maxi /= 10 ;
}
}
static void sortDates( int dates[][], int n)
{
sortDatesUtil(dates, n, 0 );
sortDatesUtil(dates, n, 1 );
sortDatesUtil(dates, n, 2 );
}
static void printArr( int arr[][], int n)
{
for ( int i = 0 ; i < 6 ; i++)
{
for ( int j = 0 ; j < 3 ; j++)
{
System.out.print(arr[i][j] + " " );
}
System.out.println();
}
}
public static void main(String[] args)
{
int dates[][] = {{ 20 , 1 , 2014 },
{ 25 , 3 , 2010 },
{ 3 , 12 , 2000 },
{ 18 , 11 , 2000 },
{ 19 , 4 , 2015 },
{ 9 , 7 , 2005 }};
int n = dates.length;
sortDates(dates,n);
System.out.print( "\nSorted Dates\n" );
printArr(dates,n);
}
}
|
Python3
import sys
def getMax(arr, n, q):
maxi = sys.maxsize;
for i in range (n):
maxi = max (maxi, arr[i][q]);
return maxi;
def sortDatesUtil(arr, n, q):
maxi = getMax(arr, n, q);
p = 1 ;
while (maxi > 0 ):
cnt = [ 0 for i in range ( 10 )];
for i in range (n):
cnt[(arr[i][q] / / p) % 10 ] + = 1 ;
for i in range ( 1 , 10 ):
cnt[i] + = cnt[i - 1 ];
ans = [[ 0 for i in range ( 3 )] for j in range (n)];
for i in range (n - 1 , - 1 , - 1 ):
lastDigit = (arr[i][q] / / p) % 10 ;
for j in range ( 3 ):
ans[cnt[lastDigit] - 1 ][j] = arr[i][j];
cnt[lastDigit] - = 1 ;
for i in range (n):
for j in range ( 3 ):
arr[i][j] = ans[i][j];
p * = 10 ;
maxi = maxi / / 10 ;
def sortDates(dates, n):
sortDatesUtil(dates, n, 0 );
sortDatesUtil(dates, n, 1 );
sortDatesUtil(dates, n, 2 );
def printArr(arr, n):
for i in range ( 6 ):
for j in range ( 3 ):
print (arr[i][j], end = " " );
print ();
if __name__ = = '__main__' :
dates = [[ 20 , 1 , 2014 ],[ 25 , 3 , 2010 ],[ 3 , 12 , 2000 ],[ 18 , 11 , 2000 ],[ 19 , 4 , 2015 ],
[ 9 , 7 , 2005 ]] ;
n = len (dates);
sortDates(dates, n);
print ( "\nSorted Dates" );
printArr(dates, n);
|
C#
using System;
public class GFG
{
static int getMax( int [,]arr, int n, int q)
{
int maxi = int .MinValue;
for ( int i = 0; i < n; i++)
{
maxi = Math.Max(maxi, arr[i,q]);
}
return maxi;
}
static void sortDatesUtil( int [,]arr,
int n, int q)
{
int maxi = getMax(arr,n,q);
int p = 1;
while (maxi > 0)
{
int []cnt = new int [10];
for ( int i = 0; i < n; i++)
{
cnt[(arr[i,q]/p) % 10]++;
}
for ( int i = 1; i < 10; i++)
{
cnt[i] += cnt[i - 1];
}
int [,]ans = new int [n,3];
for ( int i = n - 1; i >= 0; i--)
{
int lastDigit = (arr[i,q]/p) % 10;
for ( int j = 0; j < 3; j++)
{
ans[cnt[lastDigit]-1,j]
=arr[i,j];
}
cnt[lastDigit]--;
}
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < 3; j++)
{
arr[i,j] = ans[i,j];
}
}
p *= 10;
maxi /= 10;
}
}
static void sortDates( int [,]dates, int n)
{
sortDatesUtil(dates, n, 0);
sortDatesUtil(dates, n, 1);
sortDatesUtil(dates, n, 2);
}
static void printArr( int [,]arr, int n)
{
for ( int i = 0; i < 6; i++)
{
for ( int j = 0; j < 3; j++)
{
Console.Write(arr[i, j] + " " );
}
Console.WriteLine();
}
}
public static void Main(String[] args)
{
int [,]dates = {{20, 1, 2014},
{25, 3, 2010},
{ 3, 12, 2000},
{18, 11, 2000},
{19, 4, 2015},
{ 9, 7, 2005}};
int n = dates.GetLength(0);
sortDates(dates,n);
Console.Write( "\nSorted Dates\n" );
printArr(dates,n);
}
}
|
Javascript
<script>
function getMax(arr , n , q) {
var maxi = Number.MIN_VALUE;
for ( var i = 0; i < n; i++) {
maxi = Math.max(maxi, arr[i][q]);
}
return maxi;
}
function sortDatesUtil(arr , n , q)
{
var maxi = getMax(arr, n, q);
var p = 1;
while (maxi > 0)
{
var cnt = Array(10).fill(0);
for ( var i = 0; i < n; i++) {
cnt[parseInt((arr[i][q] / p)) % 10]++;
}
for ( var i = 1; i < 10; i++) {
cnt[i] += cnt[i - 1];
}
var ans = Array(n).fill().map(()=>Array(3).fill(0));
for ( var i = n - 1; i >= 0; i--) {
var lastDigit = parseInt((arr[i][q] / p) % 10);
for ( var j = 0; j < 3; j++) {
ans[cnt[lastDigit] - 1][j] = arr[i][j];
}
cnt[lastDigit]--;
}
for ( var i = 0; i < n; i++) {
for ( var j = 0; j < 3; j++) {
arr[i][j] = ans[i][j];
}
}
p *= 10;
maxi = parseInt(maxi/10);
}
}
function sortDates(dates , n) {
sortDatesUtil(dates, n, 0);
sortDatesUtil(dates, n, 1);
sortDatesUtil(dates, n, 2);
}
function printArr(arr , n) {
for ( var i = 0; i < 6; i++) {
for ( var j = 0; j < 3; j++) {
document.write(arr[i][j] + " " );
}
document.write( "<br/>" );
}
}
var dates = [ [ 20, 1, 2014 ],
[ 25, 3, 2010 ],
[ 3, 12, 2000 ],
[ 18, 11, 2000 ],
[ 19, 4, 2015 ],
[ 9, 7, 2005 ] ];
var n = dates.length;
sortDates(dates, n);
document.write( "\nSorted Dates\n" );
printArr(dates, n);
</script>
|
OutputSorted Dates
18 11 2000
3 12 2000
9 7 2005
25 3 2010
20 1 2014
19 4 2015
This article is contributed by tpriyanshu. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above