剣指offerの:40最小のk個数
3378 ワード
剣指offerの:40最小のk個数
タイトルの説明:
n個の整数を入力し、最小のk個数を見つけます.例えば、4,5,1,6,2,7,3,8の8つの数字を入力すると、最小の4つの数字は1,2,3,4である.
解法1:
入力したn個の整数を並べ替え,並べ替え後の先頭にあるk個の数が最小のk個の数である.時間複雑度O(nlogn)(高速配列).この方法は入力した配列を変更できる場合にのみ適用されます.Partitionに基づいています.
解法2:
入力した配列を変更できない場合は、最大スタックを使用できます.時間複雑度はO(nlogk).大量のデータを処理するのに適しています.まずkサイズのデータコンテナを作成して最小のk個の数字を格納し、次に入力したn個の整数から1個の数字を読み込みます.コンテナにk個未満の数字がある場合は、読み取り時に直接コンテナに格納します.コンテナにk個の数字がある場合は、コンテナがいっぱいであることを示します.この場合、これ以上挿入できません.新しい数値を入力すると、既存の数値のみが置き換えられます.既存のk個の数の最大値を見つけます.そして今回挿入する数と最大値を比較します.挿入する数が既存の最大値より小さい場合は、この数で現在の最大値を置き換えます.挿入する数が既存の最大値よりも大きい場合は、破棄できます.そのため、容器がいっぱいになったら3つのことをします:1.k個の整数の中で最大数を見つける.2.この容器から最大数を削除する可能性があります.3.新しい数値を挿入する場合があります.この容器を実現するために二叉木を使うと、この3ステップは、さらにO(logk)時間で実現することができる.したがって、n個の入力された数字に対して、総時間効率はO(nlogk)である.最大スタック:ルートノードの値は、常にそのサブツリー内の任意のノードの値よりも大きい.そこで、O(1)時間で既存のk個の数字の最大値を得ることができるが、削除および挿入操作を完了するにはO(logk)時間が必要である.
コードブロック:
解法3:
最大スタックコードは比較的困難であり、我々のコンテナを実現するために、レッドブラックツリー(ツリーがある程度バランスしていることを確保する)を採用することができる.STL(standard Template Library標準テンプレートライブラリ:1.アルゴリズム2.コンテナ3.関数4.反復器)では、setとmultisetはいずれもレッドブラックツリーに基づいて実現される.
コードブロック
タイトルの説明:
n個の整数を入力し、最小のk個数を見つけます.例えば、4,5,1,6,2,7,3,8の8つの数字を入力すると、最小の4つの数字は1,2,3,4である.
解法1:
入力したn個の整数を並べ替え,並べ替え後の先頭にあるk個の数が最小のk個の数である.時間複雑度O(nlogn)(高速配列).この方法は入力した配列を変更できる場合にのみ適用されます.Partitionに基づいています.
解法2:
入力した配列を変更できない場合は、最大スタックを使用できます.時間複雑度はO(nlogk).大量のデータを処理するのに適しています.まずkサイズのデータコンテナを作成して最小のk個の数字を格納し、次に入力したn個の整数から1個の数字を読み込みます.コンテナにk個未満の数字がある場合は、読み取り時に直接コンテナに格納します.コンテナにk個の数字がある場合は、コンテナがいっぱいであることを示します.この場合、これ以上挿入できません.新しい数値を入力すると、既存の数値のみが置き換えられます.既存のk個の数の最大値を見つけます.そして今回挿入する数と最大値を比較します.挿入する数が既存の最大値より小さい場合は、この数で現在の最大値を置き換えます.挿入する数が既存の最大値よりも大きい場合は、破棄できます.そのため、容器がいっぱいになったら3つのことをします:1.k個の整数の中で最大数を見つける.2.この容器から最大数を削除する可能性があります.3.新しい数値を挿入する場合があります.この容器を実現するために二叉木を使うと、この3ステップは、さらにO(logk)時間で実現することができる.したがって、n個の入力された数字に対して、総時間効率はO(nlogk)である.最大スタック:ルートノードの値は、常にそのサブツリー内の任意のノードの値よりも大きい.そこで、O(1)時間で既存のk個の数字の最大値を得ることができるが、削除および挿入操作を完了するにはO(logk)時間が必要である.
コードブロック:
import java.util.ArrayList;
import java.util.Comparator;
import java.util.PriorityQueue;
public class Solution {
public static ArrayList GetLeastNumbers_Solution(int [] input, int k) {
ArrayList rst = new ArrayList();
if(input.length < k || k <= 0 ){
return rst;
}
PriorityQueue maxHeap = new PriorityQueue<>(k, new Comparator() {
@Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
});
for(int i = 0; i < input.length; i++){
if (maxHeap.size() < k){
maxHeap.offer(input[i]);
}else if(maxHeap.peek() > input[i]){
Integer temp = maxHeap.poll();
temp = null;
maxHeap.offer(input[i]);
}
}
for(Integer integer : maxHeap){
rst.add(integer);
}
return rst;
}
public static void main(String[] args) {
int input[] = {4,5,1,6,2,7,3,8};
int k = 4;
ArrayList a = (ArrayList) GetLeastNumbers_Solution(input, k);
System.out.println(a);
}
}
解法3:
最大スタックコードは比較的困難であり、我々のコンテナを実現するために、レッドブラックツリー(ツリーがある程度バランスしていることを確保する)を採用することができる.STL(standard Template Library標準テンプレートライブラリ:1.アルゴリズム2.コンテナ3.関数4.反復器)では、setとmultisetはいずれもレッドブラックツリーに基づいて実現される.
コードブロック
import java.util.ArrayList;
import java.util.Iterator;
import java.util.TreeSet;
public class Solution2redblacktree {
public static ArrayList GetLeastNumbers(int[] input, int k){
ArrayList list = new ArrayList();
if(input.length <=0 || k <=0 || input.length < k){
return list;
}
TreeSet kSet = new TreeSet();
for(int i = 0 ; i < input.length; i++){
if(kSet.size() < k){
kSet.add(input[i]);
}else if(input[i] < kSet.last()){
kSet.remove(kSet.last());
kSet.add(input[i]);
}
}
Iterator iterator = kSet.iterator();
while(iterator.hasNext()){// if
list.add(iterator.next());
}
return list;
}