问题扩展讨论:
TopK问题求解方案讨论(时间复杂度,空间复杂度对比)https://blog.csdn.net/BigBug_500/article/details/102558183
public static void main(String[] args) {
//采用分治法找到数组中第k 大 的元素
int k = 3;
int[] arr = new int[]{4, 3, 6, 9, 3, 2, 8, 0};
quickSortfindNumberK(arr, 0, arr.length - 1, k);
System.out.println(Arrays.toString(arr));
System.out.println("第" + k + "大的元素为:" + arr[k]);
}
//分治法 找到第k大的元素
private static void quickSortfindNumberK(int[] arr, int start, int end, int k) {
if (start >= end) {
return;
}
int divideIndex = divideDesc(arr, start, end);
//相比于降序排序,找到第k大的元素加上这一步可以减少操作步骤,去掉这一步便可完成降序排序
if (divideIndex == k) {
return;
}
//分治法,按divideIndex将数组分成两部分达到分治的效果
quickSortfindNumberK(arr, start, divideIndex - 1, k);
quickSortfindNumberK(arr, divideIndex + 1, end, k);
}
//该方法将数组交换为降序数组,与升序数组的交换仅有 1、2处不同
//返回数组中的索引,将其划分为两部分
private static int divideDesc(int[] arr, int start, int end) {
//将开始位置作为坑,坑有divideIndex的属性
int pivot = arr[start];
int divideIndex = start;
//一轮比较的结束标志
while (start <= end) {
//循环从后向前比较指定值。如果小于指定值,end--;如果大于指定值,end位置值填入坑,并作为新坑,旧坑位置比较完成(start++),跳出
while (start <= end) {
if (arr[end] > pivot) {//1. 与升序的算法相反
divideIndex = end;
arr[start] = arr[end];
start++;
break;
}
end--;
}
//循环从前往后比较指定值,如果大于指定值,start++;如果小于指定值,start位置值填入坑,并作为新坑,旧坑位置比较完成(end--),跳出
while (start <= end) {
if (arr[start] < pivot) {//2. 与升序的算法相反
divideIndex = start;
arr[end] = arr[start];
end--;
break;
}
start++;
}
}
//!!将开始取出的中心点赋值到数组的中心位置
arr[divideIndex] = pivot;
return divideIndex;
}
//end 分治法 找到第k大的元素
更多关于找到数组中的第k大元素:https://mp.weixin.qq.com/s/LKrxeFT9S5NEAHlhHI3nSQ
分治法应用于快速排序参考:https://blog.csdn.net/BigBug_500/article/details/90899713