2排序整数数组的高效排序笛卡尔积

时间:2022-07-03 18:33:11

Need Hints to design an efficient algorithm that takes the following input and spits out the following output.

需要提示设计一个有效的算法,该算法采用以下输入并吐出以下输出。

Input: two sorted arrays of integers A and B, each of length n

输入:两个整数A和B的排序数组,每个长度为n

Output: One sorted array that consists of Cartesian product of arrays A and B.

输出:一个排序数组,由数组A和B的笛卡尔积组成。

For Example: 

Input:
A is 1, 3, 5
B is 4, 8, 10
here n is 3.

Output:
4, 8, 10, 12, 20, 24, 30, 40, 50

Here are my attempts at solving this problem.

以下是我尝试解决此问题的方法。

1) Given that output is n^2, Efficient algorithm can't do any better than O(n^2) time complexity.

1)鉴于输出为n ^ 2,有效算法不能比O(n ^ 2)时间复杂度做得更好。

2) First I tried a simple but inefficient approach. Generate Cartesian product of A and B. It can be done in O(n^2) time complexity. we need to store, so we can do sorting on it. Therefore O(n^2) space complexity too. Now we sort n^2 elements which can't be done better than O(n^2logn) without making any assumptions on the input.

2)首先,我尝试了一种简单但效率低下的方法。生成A和B的笛卡尔积。它可以在O(n ^ 2)时间复杂度下完成。我们需要存储,所以我们可以对它进行排序。因此O(n ^ 2)空间复杂度也是如此。现在我们排序n ^ 2个元素,这些元素不能比O(n ^ 2logn)做得更好,而不对输入做任何假设。

Finally I have O(n^2logn) time and O(n^2) space complexity algorithm.

最后我有O(n ^ 2logn)时间和O(n ^ 2)空间复杂度算法。

There must be a better algorithm because I've not made use of sorted nature of input arrays.

必须有一个更好的算法,因为我没有使用输入数组的排序性质。

2 个解决方案

#1


3  

If there's a solution that's better than O(n² log n) it needs to do more than just exploit the fact that A and B are already sorted. See my answer to this question.

如果有一个比O(n²logn)更好的解决方案,它需要做的不仅仅是利用A和B已经排序的事实。看看我对这个问题的回答。


Srikanth wonders how this can be done in O(n) space (not counting the space for the output). This can be done by generating the lists lazily.

Srikanth想知道如何在O(n)空间中完成(不计算输出空间)。这可以通过懒惰地生成列表来完成。

Suppose we have A = 6,7,8 and B = 3,4,5. First, multiply every element in A by the first element in B, and store these in a list:

假设我们有A = 6,7,8和B = 3,4,5。首先,将A中的每个元素乘以B中的第一个元素,并将它们存储在列表中:

6×3 = 18, 7×3 = 21, 8×3 = 24

6×3 = 18,7×3 = 21,8×3 = 24

Find the smallest element of this list (6×3), output it, replace it with that element in A times the next element in B:

找到此列表中的最小元素(6×3),输出它,用A中的元素替换为B中的下一个元素:

7×3 = 21, 6×4 = 24, 8×3 = 24

7×3 = 21,6×4 = 24,8×3 = 24

Find the new smallest element of this list (7×3), output it, and replace:

找到此列表中的新最小元素(7×3),输出并替换:

6×4 = 24, 8×3 = 24, 7×4 = 28

6×4 = 24,8×3 = 24,7×4 = 28

And so on. We only need O(n) space for this intermediate list, and finding the smallest element at each stage takes O(log n) time if we keep the list in a heap.

等等。我们只需要O(n)空间用于此中间列表,如果我们将列表保存在堆中,则在每个阶段找到最小元素需要O(log n)时间。

#2


0  

If you multiply a value of A with all values of B, the result list is still sorted. In your example:

如果将A的值与B的所有值相乘,则结果列表仍会排序。在你的例子中:

A is 1, 3, 5

A是1,3,5

B is 4, 8, 10

B是4,8,10

1*(4,8,10) = 4,8,10

1 *(4,8,10)= 4,8,10

3*(4,8,10) = 12,24,30

3 *(4,8,10)= 12,24,30

Now you can merge the two lists (exactly like in merge sort). You just look at both list heads and put the smaller one in the result list. so here you would select 4, then 8 then 10 etc. result = 4,8,10,12,24,30

现在您可以合并两个列表(与合并排序完全相同)。您只需查看两个列表头并将较小的一个放在结果列表中。所以在这里你会选择4,然后8然后10等。结果= 4,8,10,12,24,30

Now you do the same for result list and the next remaining list merging 4,8,10,12,24,30 with 5*(4,8,10) = 20,40,50.

现在你对结果列表做同样的事情,下一个剩余的列表合并4,8,10,12,24,30与5 *(4,8,10)= 20,40,50。

As merging is most efficient if both lists have the same length, you can modify that schema by dividing A in two parts, do the merging recursively for both parts, and merge both results.

如果两个列表具有相同的长度,合并最有效,则可以通过将A分为两部分来修改该模式,对两个部分进行递归合并,并合并两个结果。

Note that you can save some time using a merge approach as is isn't required that A is sorted, just B needs to be sorted.

请注意,您可以使用合并方法节省一些时间,因为不需要对A进行排序,只需要对B进行排序。

#1


3  

If there's a solution that's better than O(n² log n) it needs to do more than just exploit the fact that A and B are already sorted. See my answer to this question.

如果有一个比O(n²logn)更好的解决方案,它需要做的不仅仅是利用A和B已经排序的事实。看看我对这个问题的回答。


Srikanth wonders how this can be done in O(n) space (not counting the space for the output). This can be done by generating the lists lazily.

Srikanth想知道如何在O(n)空间中完成(不计算输出空间)。这可以通过懒惰地生成列表来完成。

Suppose we have A = 6,7,8 and B = 3,4,5. First, multiply every element in A by the first element in B, and store these in a list:

假设我们有A = 6,7,8和B = 3,4,5。首先,将A中的每个元素乘以B中的第一个元素,并将它们存储在列表中:

6×3 = 18, 7×3 = 21, 8×3 = 24

6×3 = 18,7×3 = 21,8×3 = 24

Find the smallest element of this list (6×3), output it, replace it with that element in A times the next element in B:

找到此列表中的最小元素(6×3),输出它,用A中的元素替换为B中的下一个元素:

7×3 = 21, 6×4 = 24, 8×3 = 24

7×3 = 21,6×4 = 24,8×3 = 24

Find the new smallest element of this list (7×3), output it, and replace:

找到此列表中的新最小元素(7×3),输出并替换:

6×4 = 24, 8×3 = 24, 7×4 = 28

6×4 = 24,8×3 = 24,7×4 = 28

And so on. We only need O(n) space for this intermediate list, and finding the smallest element at each stage takes O(log n) time if we keep the list in a heap.

等等。我们只需要O(n)空间用于此中间列表,如果我们将列表保存在堆中,则在每个阶段找到最小元素需要O(log n)时间。

#2


0  

If you multiply a value of A with all values of B, the result list is still sorted. In your example:

如果将A的值与B的所有值相乘,则结果列表仍会排序。在你的例子中:

A is 1, 3, 5

A是1,3,5

B is 4, 8, 10

B是4,8,10

1*(4,8,10) = 4,8,10

1 *(4,8,10)= 4,8,10

3*(4,8,10) = 12,24,30

3 *(4,8,10)= 12,24,30

Now you can merge the two lists (exactly like in merge sort). You just look at both list heads and put the smaller one in the result list. so here you would select 4, then 8 then 10 etc. result = 4,8,10,12,24,30

现在您可以合并两个列表(与合并排序完全相同)。您只需查看两个列表头并将较小的一个放在结果列表中。所以在这里你会选择4,然后8然后10等。结果= 4,8,10,12,24,30

Now you do the same for result list and the next remaining list merging 4,8,10,12,24,30 with 5*(4,8,10) = 20,40,50.

现在你对结果列表做同样的事情,下一个剩余的列表合并4,8,10,12,24,30与5 *(4,8,10)= 20,40,50。

As merging is most efficient if both lists have the same length, you can modify that schema by dividing A in two parts, do the merging recursively for both parts, and merge both results.

如果两个列表具有相同的长度,合并最有效,则可以通过将A分为两部分来修改该模式,对两个部分进行递归合并,并合并两个结果。

Note that you can save some time using a merge approach as is isn't required that A is sorted, just B needs to be sorted.

请注意,您可以使用合并方法节省一些时间,因为不需要对A进行排序,只需要对B进行排序。