【问题标题】:Find Nth element from the two unsorted Array从两个未排序的数组中找到第 N 个元素
【发布时间】:2014-08-12 16:17:15
【问题描述】:

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

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

P.S:我知道上面有很多类似的问题张贴在 SO 但我找不到任何正确的实施方式。

【问题讨论】:

  • 也可以考虑在programmers.stackexchange.com 中提问。
  • 假设一个零索引数组。你的合并数组是1 3 4 7 9,所以如果k=3,那么你应该返回7而不是4。对吧?
  • 是的,你是对的,让我们将其视为非基于零的索引。

标签: arrays sorting data-structures


【解决方案1】:

就目前而言,您的示例是错误的。

假设它的 int[] a= [3 1 7] int[] b = [4 9] k: 3 返回 7。

遍历两个数组并推送到min-heap。完成后,从堆中弹出 k 次,您将获得合并数组中的 kth (largest) 元素。

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;

}

上面的代码未经测试。但它应该大致如上所示。

【讨论】:

  • 我已经根据您的评论修改了问题,可以说它的非零索引数组。你有实现相同的代码吗?
【解决方案2】:

这个问题的总称是Selection Algorithm,维基百科上有一篇很棒的文章。

找到两个未排序数组的第 k 个元素等同于找到一个数组的第 k 个元素——只是假设你已经连接了这两个元素。链接页面中的一个简单算法是快速选择,它本质上是快速排序,但只递归到包含第 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

【讨论】:

    【解决方案3】:

    使用快速选择算法的 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;
        }
    

    【讨论】:

      猜你喜欢
      • 2017-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-20
      • 1970-01-01
      • 2021-12-16
      相关资源
      最近更新 更多