Arrays 从两个未排序的数组中查找第n个元素

Arrays 从两个未排序的数组中查找第n个元素,arrays,sorting,data-structures,Arrays,Sorting,Data Structures,给定两个未排序的int数组,在合并的排序数组中查找第k个元素。 例子: int[]a=[3 1 7] int[]b=[4 9] k:3 返回4(非零基索引) 请不要提供合并两个数组并排序并查找第n个元素的直接解决方案。我正在寻找更有效的解决方案,即使用堆、快速排序。并确保数组未排序 注:我知道上面有很多类似的问题,但我找不到任何正确的解决方法。这个问题的一般术语是,维基百科上有一篇很好的文章 查找两个未排序数组的第k个元素相当于查找一个数组的第k个元素——只要假设已将这两个数组连接起来。链接页面

给定两个未排序的int数组,在合并的排序数组中查找第k个元素。 例子: int[]a=[3 1 7] int[]b=[4 9] k:3 返回4(非零基索引)

请不要提供合并两个数组并排序并查找第n个元素的直接解决方案。我正在寻找更有效的解决方案,即使用堆、快速排序。并确保数组未排序


注:我知道上面有很多类似的问题,但我找不到任何正确的解决方法。

这个问题的一般术语是,维基百科上有一篇很好的文章

查找两个未排序数组的第k个元素相当于查找一个数组的第k个元素——只要假设已将这两个数组连接起来。链接页面中的一个简单算法是Quickselect,它本质上是快速排序,但只递归到包含第k个元素的一半。本质上

Use the first element as the pivot
Iterate over the array, assigning items <= to the pivot to one array, and > to another, until an array has grown large enough that it must contain the desired element
Recurse on that array, offsetting k if necessary
使用第一个元素作为轴心
迭代数组,将项目分配给另一个,直到数组足够大,必须包含所需的元素
在该数组上递归,必要时偏移k

就目前情况而言,你的例子是错误的

假设它的int[]a=[317]int[]b=[49]k:3返回7

在两个数组中循环并推送到
min堆
。完成后,从堆中弹出
k
次,您将拥有合并数组中的
kth(最大)
元素

PriorityQueue<Integer> minHeap=new PriorityQueue();

for (Integer i : a)
{
  minHeap.add(i);
}

for (Integer i : b)
{
  minHeap.add(i);
}
int count=1;// 1 based index
while(!minHeap.isEmpty())
{

 Integer head=minHeap.poll();
 count++;
 if(count==k)
   return head;

}
PriorityQueue minHeap=new PriorityQueue();
for(整数i:a)
{
添加(i);
}
for(整数i:b)
{
添加(i);
}
整数计数=1;//基于1的索引
而(!minHeap.isEmpty())
{
整数head=minHeap.poll();
计数++;
如果(计数=k)
回流头;
}
上面的代码未经测试。但它应该大致如上面所示。

C#使用快速选择算法的代码:

    private void MergeUnsortedArray(int[] A1, int[] A2)
    {
        int[] c = new int[A1.Length + A2.Length];
        int length = 0;
        for (int i = 0; i < A1.Length; i++)
        {
            c[i] = A2[i];
            length++;
        }
        for (int j = 0; j < A2.Length; j++)
        {
            c[length + j + 1] = A2[j];
        }
        quickselect(c, 0, c.Length, 3);
    }
    private int quickselect(int[] G, int first, int last, int k)
    {
        if (first <= last)
        {
            int pivot = partition(G, first, last);
            if (pivot == k)
            {
                return G[k];
            }
            if (pivot < k)
            {
                return quickselect(G, first, pivot - 1, k);
            }
            return quickselect(G, pivot + 1, last, k);
        }
        return 0;
    }
    private int partition(int[] G, int first, int last)
    {
        int pivot = (first + last) / 2;
        swap(G, last, pivot);
        for (int i = first; i < last; i++)
        {
            if (G[i] < G[last])
            {
                swap(G, i, first);
                first++;
            }
        }
        swap(G, first, last);
        return first;
    }
    private void swap(int[] G, int x, int y)
    {
        int tmp = G[x];
        G[x] = G[y];
        G[y] = tmp;
    }
private void mergensortedarray(int[]A1,int[]A2)
{
int[]c=新的int[A1.Length+A2.Length];
整数长度=0;
对于(int i=0;i如果(首先考虑考虑一个零索引数组)。假设你的合并数组是“代码>1×3 4×9</代码>”,所以如果<代码> k=3 < /代码>,那么你应该返回<代码> 7 < /代码>,而不是<代码> 4 < /代码>。是的,你是正确的,让我们考虑一个非零的索引。我已经根据你的注释修改了这个问题,让我们说它的非ZER。基于o的索引数组。您有实现相同的代码吗?