我们将一个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;
}
答案 0 :(得分:3)
首先,这部分非常可疑:
if (i < index - 1)
quickSort(rankBagArr, index-1 ,j);
if (index < j)
quickSort(rankBagArr, i, index-1);
你的意思是:
if (i < index - 1)
quickSort(rankBagArr, i, index-1);
if (index + 1 < j)
quickSort(rankBagArr, index + 1, j);
我不熟悉你的分区方法,所以我不知道这是否正确。我认为我理解它,它在检查时看起来没问题,但是如果没有仔细研究就很容易得到一个很难看到的错误。
这是我最近在C#中编写的分区方法 - 如果你愿意,你应该可以很容易地将它翻译成Java。
private static int Partition<T>(T[] array, int left, int right,
IComparer<T> comparer) {
// Pivot on the rightmost element to avoid an extra swap
T pivotValue = array[right];
int storeIndex = left;
for (int i = left; i < right; i++) {
if (comparer.Compare(array[i], pivotValue) < 0) {
Swap(array, i, storeIndex);
storeIndex++;
}
}
Swap(array, right, storeIndex);
return storeIndex;
}
static void Swap<T>(T[] array, int x, int y) {
T tmp = array[x];
array[x] = array[y];
array[y] = tmp;
}
不仅仅使用Arrays.sort
的任何理由?
答案 1 :(得分:1)
如果您想通过排序解决问题,那么
快速分区有利于在不对整个集合进行排序的情况下查找第k个元素 - 您进行分区,如果最小范围大于k,则您经常使用分区到较低范围,如果它小于k,则转到更高范围并寻找(k - 较低范围的大小)第 - 元素。它比分类整个集合具有更好的复杂性。您可以阅读更多相关信息here
无论如何,您的方法具有名为uniqueArr的参数,但您在rankBagArr上执行了一些操作。这是一个错字吗?您的代码中没有rankBagArr的定义。
答案 2 :(得分:0)
愿你可以减少操作(并提高性能),并纠正你所看到的默认值......
从List(ArrayList)开始,您可以要求对其进行排序(使用比较器和Collections.sort(list)
)。然后你可以循环下去: