给定两个数组A1 []和A2 [],对A1进行排序,以使元素之间的相对顺序与A2中的相对顺序相同。对于A2中不存在的元素,最后按排序顺序附加它们。
例子:
Input: A1[] = {2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8}
A2[] = {2, 1, 8, 3}
Output: A1[] = {2, 2, 1, 1, 8, 8, 3, 5, 6, 7, 9}
该代码应处理所有情况,例如与A1 []相比,A2 []中的元素数量可能更多或更少。 A2 []可能包含A1 []中可能不存在的某些元素,反之亦然。
资料来源:亚马逊访谈|套装110(校园内)
我们强烈建议您单击此处并进行实践,然后再继续解决方案。
方法1(使用排序和二进制搜索)
假设A1 []的大小为m,而A2 []的大小为n。
- 创建一个大小为m的临时数组temp,并将A1 []的内容复制到其中。
- 创建另一个访问过的数组,并将其中的所有条目初始化为false。 visit []用于标记temp []中复制到A1 []的那些元素。
- 排序温度[]
- 将输出索引ind初始化为0。
- 对A2 []中A2 [i]的每个元素进行跟踪
- 二进制搜索temp []中所有出现的A2 [i](如果存在),然后将所有出现的内容复制到A1 [ind]并递增ind。还要标记已复制的元素访问过[]
- 将所有未访问的元素从temp []复制到A1 []
下图是上述方法的模拟:
下面是上述方法的实现:
C++
// A C++ program to sort an array according to the order defined
// by another array
#include
using namespace std;
// A Binary Search based function to find index of FIRST occurrence
// of x in arr[]. If x is not present, then it returns -1
// The same can be done using the lower_bound
// function in C++ STL
int first(int arr[], int low, int high, int x, int n)
{
// Checking condition
if (high >= low) {
// FInd the mid element
int mid = low + (high - low) / 2;
// Check if the element is the extreme left
// in the left half of the array
if ((mid == 0 || x > arr[mid - 1]) && arr[mid] == x)
return mid;
// If the element lies on the right half
if (x > arr[mid])
return first(arr, (mid + 1), high, x, n);
// Check for element in the left half
return first(arr, low, (mid - 1), x, n);
}
// ELement not found
return -1;
}
// Sort A1[0..m-1] according to the order defined by A2[0..n-1].
void sortAccording(int A1[], int A2[], int m, int n)
{
// The temp array is used to store a copy of A1[] and visited[]
// is used mark the visited elements in temp[].
int temp[m], visited[m];
for (int i = 0; i < m; i++) {
temp[i] = A1[i];
visited[i] = 0;
}
// Sort elements in temp
sort(temp, temp + m);
// for index of output which is sorted A1[]
int ind = 0;
// Consider all elements of A2[], find them in temp[]
// and copy to A1[] in order.
for (int i = 0; i < n; i++) {
// Find index of the first occurrence of A2[i] in temp
int f = first(temp, 0, m - 1, A2[i], m);
// If not present, no need to proceed
if (f == -1)
continue;
// Copy all occurrences of A2[i] to A1[]
for (int j = f; (j < m && temp[j] == A2[i]); j++) {
A1[ind++] = temp[j];
visited[j] = 1;
}
}
// Now copy all items of temp[]
// which are not present in A2[]
for (int i = 0; i < m; i++)
if (visited[i] == 0)
A1[ind++] = temp[i];
}
// Utility function to print an array
void printArray(int arr[], int n)
{
// Iterate in the array
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
cout << endl;
}
// Driver Code
int main()
{
int A1[] = { 2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8 };
int A2[] = { 2, 1, 8, 3 };
int m = sizeof(A1) / sizeof(A1[0]);
int n = sizeof(A2) / sizeof(A2[0]);
// Prints the sorted array
cout << "Sorted array is \n";
sortAccording(A1, A2, m, n);
printArray(A1, m);
return 0;
}
Java
// A JAVA program to sort an array according
// to the order defined by another array
import java.io.*;
import java.util.Arrays;
class GFG {
/* A Binary Search based function to find
index of FIRST occurrence of x in arr[].
If x is not present, then it returns -1 */
static int first(int arr[], int low, int high,
int x, int n)
{
if (high >= low) {
/* (low + high)/2; */
int mid = low + (high - low) / 2;
if ((mid == 0 || x > arr[mid - 1]) && arr[mid] == x)
return mid;
if (x > arr[mid])
return first(arr, (mid + 1), high,
x, n);
return first(arr, low, (mid - 1), x, n);
}
return -1;
}
// Sort A1[0..m-1] according to the order
// defined by A2[0..n-1].
static void sortAccording(int A1[], int A2[], int m,
int n)
{
// The temp array is used to store a copy
// of A1[] and visited[] is used to mark the
// visited elements in temp[].
int temp[] = new int[m], visited[] = new int[m];
for (int i = 0; i < m; i++) {
temp[i] = A1[i];
visited[i] = 0;
}
// Sort elements in temp
Arrays.sort(temp);
// for index of output which is sorted A1[]
int ind = 0;
// Consider all elements of A2[], find them
// in temp[] and copy to A1[] in order.
for (int i = 0; i < n; i++) {
// Find index of the first occurrence
// of A2[i] in temp
int f = first(temp, 0, m - 1, A2[i], m);
// If not present, no need to proceed
if (f == -1)
continue;
// Copy all occurrences of A2[i] to A1[]
for (int j = f; (j < m && temp[j] == A2[i]);
j++) {
A1[ind++] = temp[j];
visited[j] = 1;
}
}
// Now copy all items of temp[] which are
// not present in A2[]
for (int i = 0; i < m; i++)
if (visited[i] == 0)
A1[ind++] = temp[i];
}
// Utility function to print an array
static void printArray(int arr[], int n)
{
for (int i = 0; i < n; i++)
System.out.print(arr[i] + " ");
System.out.println();
}
// Driver program to test above function.
public static void main(String args[])
{
int A1[] = { 2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8 };
int A2[] = { 2, 1, 8, 3 };
int m = A1.length;
int n = A2.length;
System.out.println("Sorted array is ");
sortAccording(A1, A2, m, n);
printArray(A1, m);
}
}
/*This code is contributed by Nikita Tiwari.*/
Python3
"""A Python 3 program to sort an array
according to the order defined by
another array"""
"""A Binary Search based function to find
index of FIRST occurrence of x in arr[].
If x is not present, then it returns -1 """
def first(arr, low, high, x, n) :
if (high >= low) :
mid = low + (high - low) // 2; # (low + high)/2;
if ((mid == 0 or x > arr[mid-1]) and arr[mid] == x) :
return mid
if (x > arr[mid]) :
return first(arr, (mid + 1), high, x, n)
return first(arr, low, (mid -1), x, n)
return -1
# Sort A1[0..m-1] according to the order
# defined by A2[0..n-1].
def sortAccording(A1, A2, m, n) :
"""The temp array is used to store a copy
of A1[] and visited[] is used mark the
visited elements in temp[]."""
temp = [0] * m
visited = [0] * m
for i in range(0, m) :
temp[i] = A1[i]
visited[i] = 0
# Sort elements in temp
temp.sort()
# for index of output which is sorted A1[]
ind = 0
"""Consider all elements of A2[], find
them in temp[] and copy to A1[] in order."""
for i in range(0, n) :
# Find index of the first occurrence
# of A2[i] in temp
f = first(temp, 0, m-1, A2[i], m)
# If not present, no need to proceed
if (f == -1) :
continue
# Copy all occurrences of A2[i] to A1[]
j = f
while (j
C#
// A C# program to sort an array according
// to the order defined by another array
using System;
class GFG {
/* A Binary Search based function to find
index of FIRST occurrence of x in arr[].
If x is not present, then it returns -1 */
static int first(int[] arr, int low,
int high, int x, int n)
{
if (high >= low) {
/* (low + high)/2; */
int mid = low + (high - low) / 2;
if ((mid == 0 || x > arr[mid - 1]) && arr[mid] == x)
return mid;
if (x > arr[mid])
return first(arr, (mid + 1), high,
x, n);
return first(arr, low, (mid - 1), x, n);
}
return -1;
}
// Sort A1[0..m-1] according to the order
// defined by A2[0..n-1].
static void sortAccording(int[] A1, int[] A2,
int m, int n)
{
// The temp array is used to store a copy
// of A1[] and visited[] is used to mark
// the visited elements in temp[].
int[] temp = new int[m];
int[] visited = new int[m];
for (int i = 0; i < m; i++) {
temp[i] = A1[i];
visited[i] = 0;
}
// Sort elements in temp
Array.Sort(temp);
// for index of output which is
// sorted A1[]
int ind = 0;
// Consider all elements of A2[], find
// them in temp[] and copy to A1[] in
// order.
for (int i = 0; i < n; i++) {
// Find index of the first occurrence
// of A2[i] in temp
int f = first(temp, 0, m - 1, A2[i], m);
// If not present, no need to proceed
if (f == -1)
continue;
// Copy all occurrences of A2[i] to A1[]
for (int j = f; (j < m && temp[j] == A2[i]); j++) {
A1[ind++] = temp[j];
visited[j] = 1;
}
}
// Now copy all items of temp[] which are
// not present in A2[]
for (int i = 0; i < m; i++)
if (visited[i] == 0)
A1[ind++] = temp[i];
}
// Utility function to print an array
static void printArray(int[] arr, int n)
{
for (int i = 0; i < n; i++)
Console.Write(arr[i] + " ");
Console.WriteLine();
}
// Driver program to test above function.
public static void Main()
{
int[] A1 = { 2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8 };
int[] A2 = { 2, 1, 8, 3 };
int m = A1.Length;
int n = A2.Length;
Console.WriteLine("Sorted array is ");
sortAccording(A1, A2, m, n);
printArray(A1, m);
}
}
// This code is contributed by nitin mittal.
PHP
= $low)
{
$mid = intval($low + ($high - $low) / 2);
if (($mid == 0 || $x > $arr[$mid - 1]) &&
$arr[$mid] == $x)
return $mid;
if ($x > $arr[$mid])
return first($arr, ($mid + 1), $high, $x, $n);
return first($arr, $low, ($mid - 1), $x, $n);
}
return -1;
}
// Sort A1[0..m-1] according to the order
// defined by A2[0..n-1].
function sortAccording(&$A1, &$A2, $m, $n)
{
// The temp array is used to store a copy
// of A1[] and visited[] is used mark the
// visited elements in temp[].
$temp = array_fill(0, $m, NULL);
$visited = array_fill(0, $m, NULL);
for ($i = 0; $i < $m; $i++)
{
$temp[$i] = $A1[$i];
$visited[$i] = 0;
}
// Sort elements in temp
sort($temp);
$ind = 0; // for index of output which is sorted A1[]
// Consider all elements of A2[], find
// them in temp[] and copy to A1[] in order.
for ($i = 0; $i < $n; $i++)
{
// Find index of the first occurrence
// of A2[i] in temp
$f = first($temp, 0, $m - 1, $A2[$i], $m);
// If not present, no need to proceed
if ($f == -1) continue;
// Copy all occurrences of A2[i] to A1[]
for ($j = $f; ($j < $m &&
$temp[$j] == $A2[$i]); $j++)
{
$A1[$ind++] = $temp[$j];
$visited[$j] = 1;
}
}
// Now copy all items of temp[] which
// are not present in A2[]
for ($i = 0; $i < $m; $i++)
if ($visited[$i] == 0)
$A1[$ind++] = $temp[$i];
}
// Utility function to print an array
function printArray(&$arr, $n)
{
for ($i = 0; $i < $n; $i++)
echo $arr[$i] . " ";
echo "\n";
}
// Driver Code
$A1 = array(2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8);
$A2 = array(2, 1, 8, 3);
$m = sizeof($A1);
$n = sizeof($A2);
echo "Sorted array is \n";
sortAccording($A1, $A2, $m, $n);
printArray($A1, $m);
// This code is contributed by ita_c
?>
Javascript
Python3
from collections import Counter
# Function to sort arr1
# according to arr2
def solve(arr1, arr2):
# Our output array
res = []
# Counting Frequency of each
# number in arr1
f = Counter(arr1)
# Iterate over arr2 and append all
# occurences of element of
# arr2 from arr1
for e in arr2:
# Appending element 'e',
# f[e] number of times
res.extend([e]*f[e])
# Count of 'e' after appending is zero
f[e] = 0
# Remaining numbers in arr1 in sorted
# order (Numbers with non-zero frequency)
rem = list(sorted(filter(
lambda x: f[x] != 0, f.keys())))
# Append them also
for e in rem:
res.extend([e]*f[e])
return res
# Driver Code
if __name__ == "__main__":
arr1 = [2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8]
arr2 = [2, 1, 8, 3]
print(*solve(arr1, arr2))
C
// A C++ program to sort an array according to the order defined
// by another array
#include
#include
// A2 is made global here so that it can be accesed by compareByA2()
// The syntax of qsort() allows only two parameters to compareByA2()
int A2[5];
// size of A2[]
int size = 5;
int search(int key)
{
int i = 0, idx = 0;
for (i = 0; i < size; i++)
if (A2[i] == key)
return i;
return -1;
}
// A custom comapre method to compare elements of A1[] according
// to the order defined by A2[].
int compareByA2(const void* a, const void* b)
{
int idx1 = search(*(int*)a);
int idx2 = search(*(int*)b);
if (idx1 != -1 && idx2 != -1)
return idx1 - idx2;
else if (idx1 != -1)
return -1;
else if (idx2 != -1)
return 1;
else
return (*(int*)a - *(int*)b);
}
// This method mainly uses qsort to sort A1[] according to A2[]
void sortA1ByA2(int A1[], int size1)
{
qsort(A1, size1, sizeof(int), compareByA2);
}
// Driver program to test above function
int main(int argc, char* argv[])
{
int A1[] = { 2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8, 7, 5, 6, 9, 7, 5 };
// A2[] = {2, 1, 8, 3, 4};
A2[0] = 2;
A2[1] = 1;
A2[2] = 8;
A2[3] = 3;
A2[4] = 4;
int size1 = sizeof(A1) / sizeof(A1[0]);
sortA1ByA2(A1, size1);
printf("Sorted Array is ");
int i;
for (i = 0; i < size1; i++)
printf("%d ", A1[i]);
return 0;
}
Sorted array is
2 2 1 1 8 8 3 5 6 7 9
时间复杂度:步骤1和2需要O(m)时间。步骤3需要O(M * Log M)时间。步骤5需要O(N Log M)时间。因此,总体时间复杂度为O(M Log M + N Log M) 。
感谢vivek提出了这种方法。
方法2(使用自平衡二进制搜索树)
我们还可以使用自平衡BST,例如AVL树,红黑树等。以下是详细步骤。
- 为A1 []中的所有元素创建一个自平衡BST。在BST的每个节点中,还应跟踪密钥和访问的bool字段的出现次数,该字段对于所有节点均初始化为false。
- 将输出索引ind初始化为0。
- 对A2 []中A2 [i]的每个元素进行跟踪
- 在BST中搜索A2 [i](如果存在),然后将所有匹配项复制到A1 [ind]并递增ind。还标记在BST节点中访问的复制元素。
- 进行BST的有序遍历,并将所有未访问的密钥复制到A1 []。
此方法的时间复杂度与以前的方法相同。请注意,在自平衡二进制搜索树中,所有操作都需要logm时间。
方法3(使用散列)
- 遍历A1 [],将每个数字的计数存储在HashMap中(键:数字,值:数字的计数)
- 遍历A2 [],检查它是否存在于HashMap中,如果存在,则将其放入输出数组中多次,并从HashMap中删除该数字。
- 对HashMap中存在的其余数字进行排序,并放入输出数组中。
感谢Anurag Sigh提出了这种方法。
下面是上述方法的实现:
Python3
from collections import Counter
# Function to sort arr1
# according to arr2
def solve(arr1, arr2):
# Our output array
res = []
# Counting Frequency of each
# number in arr1
f = Counter(arr1)
# Iterate over arr2 and append all
# occurences of element of
# arr2 from arr1
for e in arr2:
# Appending element 'e',
# f[e] number of times
res.extend([e]*f[e])
# Count of 'e' after appending is zero
f[e] = 0
# Remaining numbers in arr1 in sorted
# order (Numbers with non-zero frequency)
rem = list(sorted(filter(
lambda x: f[x] != 0, f.keys())))
# Append them also
for e in rem:
res.extend([e]*f[e])
return res
# Driver Code
if __name__ == "__main__":
arr1 = [2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8]
arr2 = [2, 1, 8, 3]
print(*solve(arr1, arr2))
2 2 1 1 8 8 3 5 6 7 9
假设我们有一个良好的哈希函数,平均插入和搜索花费O(1)时间,则步骤1和2平均花费O(m + n)时间。第三步花费O(p Log p)时间,其中p是考虑A2 []的元素后剩余的元素数。
方法4(通过编写自定义的比较方法)
我们也可以定制排序算法的比较方法来解决上述问题。例如,C语言中的qsort()允许我们传递自己的自定义比较方法。
- 如果num1和num2都在A2中,则A2中具有较低索引的数字将被视为比其他数字小。
- 如果A2中仅存在num1或num2中的一个,则该数字将被处理为小于A2中不存在的另一个数字。
- 如果两者都不在A2中,则将采用自然排序。
如果我们使用O(nLogn)时间复杂度排序算法,则此方法的时间复杂度为O(mnLogm) 。通过使用散列而不是进行线性搜索,我们可以将时间复杂度提高到O(mLogm) 。
下面是上述方法的实现:
C
// A C++ program to sort an array according to the order defined
// by another array
#include
#include
// A2 is made global here so that it can be accesed by compareByA2()
// The syntax of qsort() allows only two parameters to compareByA2()
int A2[5];
// size of A2[]
int size = 5;
int search(int key)
{
int i = 0, idx = 0;
for (i = 0; i < size; i++)
if (A2[i] == key)
return i;
return -1;
}
// A custom comapre method to compare elements of A1[] according
// to the order defined by A2[].
int compareByA2(const void* a, const void* b)
{
int idx1 = search(*(int*)a);
int idx2 = search(*(int*)b);
if (idx1 != -1 && idx2 != -1)
return idx1 - idx2;
else if (idx1 != -1)
return -1;
else if (idx2 != -1)
return 1;
else
return (*(int*)a - *(int*)b);
}
// This method mainly uses qsort to sort A1[] according to A2[]
void sortA1ByA2(int A1[], int size1)
{
qsort(A1, size1, sizeof(int), compareByA2);
}
// Driver program to test above function
int main(int argc, char* argv[])
{
int A1[] = { 2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8, 7, 5, 6, 9, 7, 5 };
// A2[] = {2, 1, 8, 3, 4};
A2[0] = 2;
A2[1] = 1;
A2[2] = 8;
A2[3] = 3;
A2[4] = 4;
int size1 = sizeof(A1) / sizeof(A1[0]);
sortA1ByA2(A1, size1);
printf("Sorted Array is ");
int i;
for (i = 0; i < size1; i++)
printf("%d ", A1[i]);
return 0;
}
Sorted Array is 2 2 1 1 8 8 3 5 5 5 6 6 7 7 7 9 9