这是我参与更文挑战的第11天,活动详情查看: [更文挑战]
你好呀,我是灰小猿,一个超会写bug的程序猿!
欢迎大家关注我的专栏“每日蓝桥”,该专栏的主要作用是和大家分享近几年蓝桥杯省赛及决赛等真题,解析其中存在的算法思想、数据结构等内容,帮助大家学习到更多的知识和技术!
标题:快速排序
以下代码可以从数组a[]中找出第k小的元素
它使用了类似于快速排序中的分治算法,期望时间复杂度是O(N)的,
请仔细阅读分析源码,填写划线部分缺失的内容
package 一八年省赛真题; import java.util.Random; public class Main { public static int quickSelect(int a[],int l,int r,int k) { Random rand = new Random(); int p = rand.nextInt(r-l+1) + l; int x = a[p]; int tmp = a[p]; a[p] = a[r]; a[r] = tmp; int i = l, j = r; while (i<j) { while (i<j&&a[i]<x) i++; if (i<j) { a[j] = a[i]; j--; } while (i<j&&a[j]>x) j--; if (i<j) { a[i] = a[j]; i++; } } a[i] = x; p = i; if(i - l + 1 == k) return a[i]; if(i - l + 1 < k) return quickSelect(_______________); //填空 else return quickSelect(a, l, i - 1, k); } public static void main(String[] args) { int a[] = {1,4,2,8,5,7}; System.out.println(quickSelect(a, 0, 5, 4)); } }
注意:只提交划线部分缺少的代码,不要抄写任何已经存在的代码或符号。
解题思路
本题在求解的时候根据题意就应该采用快速排序中的分治法来进行思考,该方法的基本思想是:采用了一种分治的策略,将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。
然后我们可以很显然的看到最后填空的部分是一个递归,那么一定是子问题。所以根据else后面的代码,就可以推出正确答案。
关于这几种常用排序的基本思路,大家可以看我的这篇文章:“用大白话和面试官扯“八大常用排序算法的基本思想””
答案源码:
package 一八年省赛真题; import java.util.Random; public class Year2018_Bt5 { public static int quickSelect(int a[],int l,int r,int k) { Random rand = new Random(); int p = rand.nextInt(r-l+1) + l; int x = a[p]; int tmp = a[p]; a[p] = a[r]; a[r] = tmp; int i = l, j = r; while (i<j) { while (i<j&&a[i]<x) i++; if (i<j) { a[j] = a[i]; j--; } while (i<j&&a[j]>x) j--; if (i<j) { a[i] = a[j]; i++; } } a[i] = x; p = i; if(i - l + 1 == k) return a[i]; if(i - l + 1 < k) return quickSelect(a, i + 1, r, k - i + l - 1); //填空 else return quickSelect(a, l, i - 1, k); } public static void main(String[] args) { int a[] = {1,4,2,8,5,7}; //1,2,4,5,7,8 //输出5 System.out.println(quickSelect(a, 0, 5, 6)); } }
输出样例:
其中有不足或者改进的地方,还希望小伙伴留言提出,一起学习!
感兴趣的小伙伴可以关注专栏!
灰小猿陪你一起进步!