有时候会突然被问到一些算法题,也是面试经常被问的思路问题吧,毕竟是师兄们面试回来说的面试考题。在这一系列呢,打算把自己每次被问到的仔细思考过的一些题都总结下来。方便自己去温习吧,也给大家参考一下我的思路。
文章结构:(1)题目描述;(2)快排思路解法;(3)堆排思路解法;(4)其他解法思路待续。
一、题目描述:
找出一个整型数组中第k大的数,并输出其下标。其中数组中的数有重复,重复的数据位置全部输出。
二、快排思路解法:
public class SearchNumData {
public static int findKth(int[] a, int n, int K) {
return findKth(a, 0, n - 1, K);
}
public static int findKth(int[] a, int start, int end, int k) {
int pivot = partation(a, start, end);
if (k == pivot - start + 1){
return a[pivot];
} else if (k > pivot - start + 1) {
return findKth(a, pivot + 1, end, k - pivot + start - 1);
} else{
return findKth(a, start, pivot - 1, k);
}
}
public static int partation(int[] a, int low, int high) {
int key = a[low];
while (low < high) {
while (low < high && a[high] <= key)
high--;
a[low] = a[high];
while (low < high && a[low] >= key)
low++;
a[high] = a[low];
}
a[low] = key;
return low;
}
public static void main(String[] args) {
int[] array = {
9, 1, 5, 3, 5, 2, 6, 8, 7, 6
};
int [] array2 = array.clone();
int k=findKth(array,array.length,4);
System.out.print(k);
System.out.print("\n");
for(int i=0;i<10;i++){
System.out.print(array[i]+" ");
}
System.out.print("\n");
for(int i=0;i<10;i++){
if (k==array2[i]){
System.out.print(" 位置"+i+" ");
}
}
}
}
打印如下:
6
9 7 8 6 5 2 6 3 5 1
位置6 位置9
三、堆排思路解法:
public class HeapSearchNumData {
public static int findLeast(int[] nums, int k) {
PriorityQueue q = new PriorityQueue(k);
for (int i : nums) {
q.offer(i);
if (q.size() > k) {
q.poll();
}
}
return q.peek();
}
public static void main(String[] args) {
int[] array = {
9, 1, 5, 3, 5, 2, 6, 8, 7, 6
};
int k=findLeast(array,4);
System.out.print(k);
System.out.print("\n");
for(int i=0;i<10;i++){
System.out.print(array[i]+" ");
}
System.out.print("\n");
for(int i=0;i<10;i++){
if (k==array [i]){
System.out.print(" 位置"+i+" ");
}
}
}
}
打印如下:
6
9 1 5 3 5 2 6 8 7 6
位置6 位置9
大家是不是看到了一个Java类PriorityQueue
一个基于优先级堆的极大优先级队列。此队列按照在构造时所指定的顺序对元素排序,既可以根据元素的自然顺序来指定排序(参阅 Comparable),也可以根据 Comparator 来指定,这取决于使用哪种构造方法。优先级队列不允许 null 元素。依靠自然排序的优先级队列还不允许插入不可比较的对象。
默认:此队列的头是按指定排序方式的最小元素。
查询操作: poll、remove、peek 和 element 访问处于队列头的元素。
插入操作:此实现为插入方法(offer 和 add 方法)
删除:remove,poll
一个demo基本解出此类用法:更详细的文档
public class TestPriorityQueue {
public static void main(String[] args) {
PriorityQueue pq = new PriorityQueue(3);
int[] array = {
9, 1, 5, 3, 5, 2, 6, 8, 7, 6
};
for (int i = 0; i < array.length; i++) {
pq.offer(array[i]);
System.out.print("\n");
Object[] a =pq.toArray();
for (int j =0;jout.print(a[j]);
}
}
}
}
打印如下:
9
19
195
1359
13595
132955
1329556
13285569
132755698
1327556986
四、其他解法思路待续:
(1)耿直的排序,直接取值法:
public static int findNum(int[] nums, int k) {
Arrays.sort(nums);
return nums[nums.length - k];
}
(2)利用哈希:
建立一个二维索引表,一维记录数组内容,另一维记录下标,对内容进行排序。元素有重复,但下标不会有重复。取到那个k内容,就是根据哈希取下标了。
源码下载:辅助的数据结构与算法系列(基础知识笔记跟题目会慢慢列出来)
好了,算法题(一)–找出数组中第k大的数并输出其下标(数组中的数有重复)讲完了。本博客系列是我学习过程中,被人问到的面试题(虽然大二的我还没到面试阶段,但既然被问到了,就做下咯,这些解法思路还是很开拓视野的),每遇一题我都会认真思考,列出多项解决之道给大家,分享经验给大家。欢迎在下面指出错误,共同学习!!你的点赞是对我最好的支持!!
更多内容,可以访问JackFrost的博客