问题:求一个数组中第k大的数?
这个问题真的是有手就行,但是要写到漂亮确实得好好看一下。
1.排序!
先排序,在根据索引求出第k大的数 时间复杂度:O(log(n)*n),空间复杂度O(1) 学过java的都能想的出来,但是面试官会问你,还有其它方法吗?
import java. util. Arrays ;
class Main {
public static void main ( String [ ] args) {
int [ ] nums = new int [ ] { 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 } ;
int k= 9 ;
Arrays . sort ( nums) ;
System . out. println ( nums[ nums. length- 1 ] ) ;
}
}
2.小根堆
根据存储一个包含k元素的小根堆,堆顶就是第k小的,比第k还要小的都已经被移除掉了。 时间复杂度:O(lg(n)*n),空间复杂度O(n) 当你把这个写出来了,面试官会比较满意,可能接着会问你PriorityQueue是基于什么数据结构实现的:答案是二叉。
import java. util. PriorityQueue ;
class Main {
static PriorityQueue < Integer > que = new PriorityQueue < > ( ) ;
public static void main ( String [ ] args) {
int [ ] nums = new int [ ] { 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 } ;
int k= 9 ;
for ( int i: nums) {
add ( i, k) ;
}
System . out. println ( que. peek ( ) ) ;
}
static void add ( int x, int k) {
que. add ( x) ;
if ( que. size ( ) > k) {
que. poll ( ) ;
}
}
}
3.二分查找
基于快速排序的思想(可以定位出某个元素在排序后的数组下标)+二分查找 时间复杂度:O(logz^(n)*n),空间复杂度O(1) 你要写到这里,面试官会非常满意!!!
class Main {
public static void main ( String [ ] args) {
int [ ] nums = new int [ ] { 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 } ;
int k= 9 ;
int l= 0 ;
int r= nums. length- 1 ;
while ( l<= r) {
int m= partition ( l, r, nums) ;
if ( m == nums. length- k) {
System . out. println ( nums[ m] ) ;
break ;
} else if ( m > nums. length- k) {
r= m- 1 ;
} else {
l= m+ 1 ;
}
}
}
public static int partition ( int l, int r, int nums[ ] ) {
int flag= l;
int index= l+ 1 ;
for ( int i= index; i<= r; i++ ) {
if ( nums[ i] < nums[ flag] ) {
int temp= nums[ index] ;
nums[ index] = nums[ i] ;
nums[ i] = temp;
index++ ;
}
}
int temp= nums[ index- 1 ] ;
nums[ index- 1 ] = nums[ flag] ;
nums[ flag] = temp;
return index- 1 ;
}
}