给定N个包含重复键和值的键/值对,任务是存储这些对并按键对对进行排序。
例子:
Input :
N : 10
Keys : 5 1 4 6 8 0 6 6 5 5
values: 0 1 2 3 4 5 6 7 8 9
Output :
Keys : 0 1 4 5 5 5 6 6 6 8
values: 5 1 2 0 8 9 3 6 7 4
Explanation:
We have given 10 key, value pairs which contain duplicate keys and values.
The key value pair is {(5, 0), (1, 1), (4, 2), (6, 3), (8, 4), (0, 5), (6, 6),
(6, 7), (5, 8), (5, 9)} and we want to store these key value pair and sort these
key value pair by keys. So, the expected output is {(0, 5), (1, 1), (4, 2), (5, 0),
(5, 8), (5, 9), (6, 3), (6, 6), (6, 7), (8, 4)}. Because the sorted
increasing order of keys is {0, 1, 4, 5, 5, 5, 6, 6, 6, 8}.
方法:
为了解决上述问题,我们可以使用单独的数组存储键和值,然后可以简单地通过Merge排序算法对键进行排序。我们可以使用任何排序算法,但Mergesort是最快的标准排序算法,并且并行地,我们可以对在键上执行的values数组执行相同的操作,以便键值对将在两个数组上保持相同的索引。
下面是上述方法的实现:
Java
// Java program to Store duplicate
// keys-values pair and sort the
// key-value pair by key
import java.util.*;
import java.lang.*;
import java.io.*;
class Solution {
// Merges two subarrays of arr[].
// First subarray is arr[l..m]
// Second subarray is arr[m+1..r]
void merge(int arrk[], int l, int m,
int r, int arrv[])
{
// Sizes of two subarrays
// that are to be merged
int n1 = m - l + 1;
int n2 = r - m;
/* Create temporary arrays */
int L[] = new int[n1];
int R[] = new int[n2];
int Lk[] = new int[n1];
int Rk[] = new int[n2];
/* Copy data to temporary arrays */
for (int i = 0; i < n1; ++i) {
L[i] = arrk[l + i];
Lk[i] = arrv[l + i];
}
for (int j = 0; j < n2; ++j) {
R[j] = arrk[m + 1 + j];
Rk[j] = arrv[m + 1 + j];
}
// Initial indexes of
// first and second subarrays
int i = 0, j = 0;
int k = l;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arrk[k] = L[i];
arrv[k] = Lk[i];
i++;
}
else {
arrk[k] = R[j];
arrv[k] = Rk[j];
j++;
}
k++;
}
/* Copy remaining elements of L[] if any */
while (i < n1) {
arrk[k] = L[i];
arrv[k] = Lk[i];
i++;
k++;
}
/* Copy remaining elements of R[] if any */
while (j < n2) {
arrk[k] = R[j];
arrv[k] = Rk[j];
j++;
k++;
}
}
// Function that sorts arr[l..r] using merge()
void sort(int arrk[], int l, int r, int arrv[])
{
if (l < r) {
// Find the middle point
int m = (l + r) / 2;
// Sort first and second halves
sort(arrk, l, m, arrv);
sort(arrk, m + 1, r, arrv);
// Merge the sorted halves
merge(arrk, l, m, r, arrv);
}
}
/* Function to print array of size n */
static void printArray(int arr[])
{
int n = arr.length;
for (int i = 0; i < n; ++i)
System.out.print(arr[i] + " ");
System.out.println();
}
// Driver code
public static void main(String[] args)
throws java.lang.Exception
{
// Size of Array
int n = 10;
// array of keys
int[] arrk = { 5, 1, 4, 6, 8, 0,
6, 6, 5, 5 };
// array of values
int[] arrv = { 0, 1, 2, 3, 4, 5,
6, 7, 8, 9 };
Solution ob = new Solution();
ob.sort(arrk, 0, n - 1, arrv);
System.out.print("Keys: ");
printArray(arrk);
System.out.println();
System.out.print("Values: ");
printArray(arrv);
}
}
C#
// C# program to Store duplicate
// keys-values pair and sort the
// key-value pair by key
using System;
class Solution{
// Merges two subarrays of arr[].
// First subarray is arr[l..m]
// Second subarray is arr[m+1..r]
void merge(int []arrk, int l, int m,
int r, int []arrv)
{
// Sizes of two subarrays
// that are to be merged
int n1 = m - l + 1;
int n2 = r - m;
// Create temporary arrays
int []L = new int[n1];
int []R = new int[n2];
int []Lk = new int[n1];
int []Rk = new int[n2];
// Copy data to temporary arrays
for(int i = 0; i < n1; ++i)
{
L[i] = arrk[l + i];
Lk[i] = arrv[l + i];
}
for(int j = 0; j < n2; ++j)
{
R[j] = arrk[m + 1 + j];
Rk[j] = arrv[m + 1 + j];
}
// Initial indexes of
// first and second subarrays
int a = 0 , b = 0;
int k = l;
while (a < n1 && b < n2)
{
if (L[a] <= R[b])
{
arrk[k] = L[a];
arrv[k] = Lk[a];
a++;
}
else
{
arrk[k] = R[b];
arrv[k] = Rk[b];
b++;
}
k++;
}
// Copy remaining elements of L[] if any
while (a < n1)
{
arrk[k] = L[a];
arrv[k] = Lk[a];
a++;
k++;
}
// Copy remaining elements of R[] if any
while (b < n2)
{
arrk[k] = R[b];
arrv[k] = Rk[b];
b++;
k++;
}
}
// Function that sorts arr[l..r] using merge()
void sort(int []arrk, int l, int r, int []arrv)
{
if (l < r)
{
// Find the middle point
int m = (l + r) / 2;
// Sort first and second halves
sort(arrk, l, m, arrv);
sort(arrk, m + 1, r, arrv);
// Merge the sorted halves
merge(arrk, l, m, r, arrv);
}
}
// Function to print array of size n
static void printArray(int []arr)
{
int n = arr.Length;
for(int i = 0; i < n; ++i)
Console.Write(arr[i] + " ");
Console.WriteLine();
}
// Driver code
public static void Main(string[] args)
{
// Size of Array
int n = 10;
// array of keys
int[] arrk = { 5, 1, 4, 6, 8,
0, 6, 6, 5, 5 };
// array of values
int[] arrv = { 0, 1, 2, 3, 4,
5, 6, 7, 8, 9 };
Solution ob = new Solution();
ob.sort(arrk, 0, n - 1, arrv);
Console.Write("Keys: ");
printArray(arrk);
Console.WriteLine();
Console.Write("Values: ");
printArray(arrv);
}
}
// This code is contributed by ukasp
Javascript
Keys: 0 1 4 5 5 5 6 6 6 8
Values: 5 1 2 0 8 9 3 6 7 4
时间复杂度: O(N * logN)