标签:
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
方法一:快排思想
找到排列后的第k个数的id就好了
import java.util.ArrayList;
import java.util.TreeSet;
public class Solution {
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
ArrayList<Integer> result = new ArrayList<Integer>();
if(input == null || k<=0 || k>input.length)
return result;
int left = 0;
int right = input.length - 1;
int id = partition(input,left,right);
k = k - 1;// 下标转化为0 开始
while(id !=k){
if(id>k){
right = id - 1;
id = partition(input,left,right);
}else{
left = id + 1;
id = partition(input,left,right);
}
}
for(int i=0;i<=id;i++){
result.add(input[i]);
}
return result;
}
// 划分位置
public int partition(int [] A,int low ,int high){
int x = A[high];
int i = low - 1;// i 记录较大数id j 较小数id
for( int j = low;j<= high - 1;j++){
if( A[j] <= x){
i = i + 1;
swap(A,i,j);
}
}
i = i + 1;
swap(A,i,high);
return i;
}
public void swap(int[] input,int i,int j){
int tmp = input[i];
input[i] = input[j];
input[j] = tmp;
}
}
下面快排的程序要好好理解
i:较大数的id
j:较小数的id
当A[j] <=x的时候,i j元素进行互换
public int partition(int [] A,int low ,int high){
int x = A[high];
int i = low - 1;// i 记录较大数id j 较小数id
for( int j = low;j<= high - 1;j++){
if( A[j] <= x){
i = i + 1;
swap(A,i,j);
}
}
i = i + 1;
swap(A,i,high);
return i;
}
Partition函数也可以这样写
两个指针两侧找,左侧找到较大数,右侧找到较小数,互换,两指针相遇时候结束
public int Paratition(int[] A,int left ,int right){
if(left> right)
return -1;
int i = left;
int j = right;
int mid = A[left];
if(i<j){
while(i<j){
while(i<j && mid< A[j])
j--;
if(i<j){
A[i] = A[j];
i++;
}
while(i<j && A[i]< mid)
i++;
if(i<j){
A[j] = A[i];
j--;
}
}
A[i] = mid;
}
return i;
}
方法二:大顶堆
题目要求找到最小的k个数,建立k个元素的大顶堆
先将堆中添加k个元素,并调整为大顶堆
剩余的元素,每次加入一个元素,当这个元素比堆顶的元素还要大,不加入到堆中
当这个元素比堆顶元素小,用这个元素替换堆顶元素,并调整为大顶堆
最后堆内的k个元素就是最小的k个元素
这个思想适合在大量数据中找到最小的k个数
时间复杂度
标签:
原文地址:http://blog.csdn.net/qunxingvip/article/details/51736662