Arrays 从两个未排序的数组中查找第n个元素
给定两个未排序的int数组,在合并的排序数组中查找第k个元素。 例子: int[]a=[3 1 7] int[]b=[4 9] k:3 返回4(非零基索引) 请不要提供合并两个数组并排序并查找第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个元素——只要假设已将这两个数组连接起来。链接页面
注:我知道上面有很多类似的问题,但我找不到任何正确的解决方法。这个问题的一般术语是,维基百科上有一篇很好的文章 查找两个未排序数组的第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的索引数组。您有实现相同的代码吗?