查找数组实现包中的第 k 个最大元素
我们有一个放在袋子里的Comparable
集合,并且必须找到第k
最大的元素。我将集合复制到 HashSet 以删除重复项,然后将 HashSet 转换为要排序的数组,从而访问第 k 个元素。代码可以编译,但测试失败,我不知道出了什么问题。有什么想法吗?
public E kth(int k) {
uniqueSet();
Object[] uniqueArr = hashSet.toArray();
startQuick(uniqueArr);
return (E) uniqueArr[k - 1];
}
private void startQuick(Object[] uniqueArr) {
int i = 0, j = uniqueArr.length;
quickSort(uniqueArr, 0, j);
}
private void quickSort(Object[] uniqueArr, int i, int j) {
int index = partition(uniqueArr, i, j);
if (i < index - 1) {
quickSort(rankBagArr, index - 1, j);
}
if (index < j) {
quickSort(rankBagArr, i, index - 1);
}
}
private int partition(Object[] uniqueArr, int i, int j) {
E tmp;
E pivot = (E) rankBagArr[(i + j) / 2];
while (i <= j) {
while (rankBagArr[i].compareTo(pivot) < 0) {
i++;
}
while (rankBagArr[j].compareTo(pivot) > 0) {
j--;
}
if (i <= j) {
tmp = (E) rankBagArr[i];
rankBagArr[i] = rankBagArr[j];
rankBagArr[j] = tmp;
i++;
j--;
}
}
return i;
}
We have a collection of Comparable
s held in a bag and have to find the k
th largest element. I copied the collection to a HashSet
to remove duplicates, then converted the HashSet
to an array to be sorted and consequently the k
th element accessed. The code compiles, but fails the testing, and I can't figure out what's wrong. Any ideas?
public E kth(int k) {
uniqueSet();
Object[] uniqueArr = hashSet.toArray();
startQuick(uniqueArr);
return (E) uniqueArr[k - 1];
}
private void startQuick(Object[] uniqueArr) {
int i = 0, j = uniqueArr.length;
quickSort(uniqueArr, 0, j);
}
private void quickSort(Object[] uniqueArr, int i, int j) {
int index = partition(uniqueArr, i, j);
if (i < index - 1) {
quickSort(rankBagArr, index - 1, j);
}
if (index < j) {
quickSort(rankBagArr, i, index - 1);
}
}
private int partition(Object[] uniqueArr, int i, int j) {
E tmp;
E pivot = (E) rankBagArr[(i + j) / 2];
while (i <= j) {
while (rankBagArr[i].compareTo(pivot) < 0) {
i++;
}
while (rankBagArr[j].compareTo(pivot) > 0) {
j--;
}
if (i <= j) {
tmp = (E) rankBagArr[i];
rankBagArr[i] = rankBagArr[j];
rankBagArr[j] = tmp;
i++;
j--;
}
}
return i;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
首先,这部分非常可疑:
您不是说:
?
我不熟悉你的分区方法,所以我不知道这是否正确。我认为我理解它,并且检查起来看起来还不错,但是很容易出现一点点错误,如果不仔细研究,很难发现这些错误。
这是我最近用 C# 编写的一个分区方法 - 如果您愿意,您应该能够很容易地将其转换为 Java。
不只是使用
Arrays.sort
?For a start this part is highly suspect:
Don't you mean:
?
I'm not familiar with your approach to partitioning, so I don't know whether that's correct or not. I think I understand it, and it looks okay on inspection, but it's very easy to get off-by-one errors which are hard to see without careful study.
Here's a partition method I wrote in C# recently - you should be able to translate it into Java quite easily if you want to.
Any reason for not just using
Arrays.sort
though?如果你想通过排序来解决问题,那么
快速排序分区适用于查找第 k 个元素,而无需对整个集合进行排序 - 您进行分区,如果最低范围大于 k,则您经常将分区划分到较低范围,如果它小于 k,则转到较高范围并查找(k - 较低范围的大小)第一个元素。它比对整个集合进行排序具有更好的复杂性。您可以在此处阅读更多相关信息。
无论如何,您的方法具有名为 uniqueArr 的参数,但是您可以执行某些操作在rankBagArr 上执行。是拼写错误吗?您的代码中没有rankBagArr 的定义。
If you want to solve the problem by sorting, then
The quicksort partitioning is good for finding k-th element without sorting entire collection - you partition, if lowest range is larger then k, you recurrently go with partition to lower range, if it's smaller then k, you go to higher range and look for (k - size of lower range)-th element. It has better complexity than sorting whole collection. You can read more about it here
Anyway, your methods have parameter named uniqueArr, but some operations you perform on rankBagArr. Is it a typo? There is no definition of rankBagArr in your code.
希望您可以少一些操作(并提高性能),并更正您所看到的默认值...
从列表(ArrayList)开始,您可以要求对其进行排序(使用比较器和 Collections.List )。排序(列表))。然后你可以向下循环:
May you could have a bit less of manipulations (and improve performance), and correct the default you are seeing...
Starting with a List (ArrayList), you could ask to sort it (using the comparator, and
Collections.sort(list)
). Then you could loop down and: