学习思路:课上理解算法思想,课下记忆代码并上手题目,每道题目代码写上3到5遍,重复记忆。
Acwing在线题库
算法思想:分治策略
时间复杂度:0(nlogn)
算法步骤:
上代码:
void quick_sort(int q[],int l,int r){ if(l>=r) return; int x=q[l]; int i=l-1,j=r+1; while(i<j){ while(q[++i]<x); //相当于do i++; while(q[i]<x); while(q[--j]>x); //相当于do j--; while(q[j]>x); if(i<j) swap(i,j); } quick_sort(q,l,j); quick_sort(q,j+1,r); }
题目:给定一个长度为 n 的整数数列,以及一个整数 k,请用快速选择算法求出数列从小到大排序后的第 k个数。
输入格式
第一行包含两个整数 n 和 k。
第二行包含 n 个整数(所有整数均在 1∼1091∼109 范围内),表示整数数列。
输出格式
输出一个整数,表示数列的第 k 小数。
对于求第k个数的问题,我们很容易想到使用排序法解决,但是排序算法的时间复杂度最小也是0(nlogn),那么怎样才能更加优雅高效的解决第k小数的问题呢,这就不得不要说一说快速选择算法了。
快速选择算法是基于快速排序算法的变形,它的总体思路和快速排序是一样的,选择一个元素作为基准元素,将小于基准的元素和大于基准的元素分别放在左右两边,不同的是,快速选择算法每次不用递归访问左右两边,而是递归进入其中一边继续进行查找,这就将平均时间复杂度从O(nlogn)降到了O(n)。
算法步骤:
快速选择代码:
quick_select(q[],int l,int r,int k){ //寻找第k小的数 int x = q[l]; int i = l-1,j = r+1; if(l == r) return q[l]; while(i < j){ while(q[++ i] < x); while(q[-- j] > x); if(i < j) swap(q[i],q[j]); } int sl = j - l + 1; if(k <= s1) return quick_select(q,l,j,k); else return quick_select(q,j+1,r,k-s1); }
啊啊啊,调试了好久才通过,代码太生疏了