题目描述:
在数组中找到第ķ大的元素。
注意事项
你可以交换数组中的元素的位置
样例
给出数组 [9,3,2,4,8]
,第三大的元素是 4
给出数组 [1,2,3,4,5]
,第一大的元素是 5
,第二大的元素是 4
,第三大的元素是 3
,以此类推
本人使用的Java进行编程
要获取第ķ大的值,如果要先进行排序(如冒泡排序),则耗时非常的长。我在网上找到了一种使用快速排序的解法,引发了我的思维风暴,然后尝试用平均值进行查找。
解题思路:
1.先将数组转化成列表对象,这样就可以方便的进行存取其中的元素。
2.计算出数组中所有元素的平均值
3.把每一个元素与平均值进行比较,把大于等于平均值的放在列表1中,把小于平均值的放在列表2中
3.判断列表1里面的元素个数是否大于K,如果大于K,则说明第ķ个元素在列表1中,如果小于K,说明则第ķ个元素在列表2中。
4.选中第ķ个元素所在的列表中,再重复2〜4中的内容,进行筛选。
5.终止条件:在第3步中,一旦遇到list1里的元素的个数小于K之后,则要将K = K - list1.size();直到K = 1时跳出循环,并得到一个新的名单(第4步中返回一个列表)。
6.最后,在得到列表中找出最大的一个数,就是该题目的解。
附带java源代码。
class Solution {
/*
* @param k : description of k
* @param nums : array of nums
* @return: description of return
*/
private float sum =0;//求和公式
private float average = 0;//求平均值
private float yi=-1;//把k的值存放到全局变量中。
private int result =0;
private List<Integer> list1 = new ArrayList<Integer>();
private List<Integer> list2 = new ArrayList<Integer>();
private List<Integer> temp = new ArrayList<Integer>();
public int kthLargestElement(int k, int[] nums) {
// write your code here
//先获得该数组的长度
yi =k;
if(nums.length==1&&k==1){
return nums[0];
}
//将数组添加到list中
for(int i=0;i<nums.length;i++){
temp.add(nums[i]);
}
while(yi !=1){
//先算出平均值
average(temp);
//然后将把高于平均值的放在一个数组中,把低于平均值的放在另一个数组中
sort(temp,average);
//选择其中一个数组
temp.clear();
temp = new ArrayList<Integer> (select(list1,list2,yi));
list1.clear();
list2.clear();
}
//当yi等于1的时候,则说明,我们要的数字在temp数组中是最大的。
for(int i=0;i<temp.size()-1;i++){
if(temp.get(i)>temp.get(i+1)){
temp.set(i+1, temp.get(i));
}
}
result = temp.get(temp.size()-1);
/* 当数据量过大时,需要花费太长时间
* //使用冒泡排序进行从大到小的排序
int temp = -1;
for(int i=0;i<x;i++){
for(int j=0;j<x-i-1;j++){
if(nums[j]<nums[j+1]){
temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] =temp;
}
}
}
return nums[k-1];*/
return result;
}
public void average(List<Integer> list){
sum=0;
for(int i=0;i<list.size();i++){
sum =sum + list.get(i);
}
average = sum/list.size();
}
//得出第K大的值在那个数组中
public List<Integer> select(List<Integer> list1,List<Integer> list2,float x){
if(list1.size()< x){
//如果长度小于x,则说明第k大的值在list2中
yi=x-list1.size();
return list2;
}
return list1;
}
//把一个数组以平均值分成大于等于平均值的数组list1,和小于平均值的数组list2
public void sort(List<Integer> list,float average2){
for(int i=0;i<list.size();i++){
if(average2<=list.get(i)){
//把高于平均值的放在list1中
list1.add(list.get(i));
}else{
list2.add(list.get(i));
}
}
}
};