記事ディレクトリ
k番目に小さい数O(N)
高速ソートのアイデアを改善するO(N)最悪の場合、複雑さはO(n ^ 2)です(ソートが順序に近い場合)
public static int findk(int[] nums,int m,int n ,int k)
{
int temp=nums[m];
int i=m;
int j=n;
while(i<j)
{
while(i<j&&nums[j]>=temp)
{
j--;
}
while(i<j&&nums[i]<=temp)
{
i++;
}
if(i<j)
{
int t=nums[i];
nums[i]=nums[j];
nums[j]=t;
}
}
nums[m]=nums[j];
nums[j]=temp;
if(j+1==k)
{
return nums[j];
}
else if(j+1>k){
return findk(nums, m, j-1, k);
}
else {
return findk(nums, j+1, n, k-j-1);
}
}
public static void main(String[] args) {
int[] nums=new int[]{
8,3,6,9,2};
System.out.println(findk(nums, 0, nums.length-1, 4));
}
bfprtアルゴリズム(5つのMITビッグカウのイニシャル)は、最悪の場合、O(n)の複雑さを持っています。
- ランダムに数mを選択します(bfprtと上記の違いはここにあります、bfprtは慎重に番号を選択し、可能な限り多くの番号を削除します)。
- <mを左に置くm> mを右に置く
- リターンを押し、ミスした場合は、左右を選択して再帰を続行します
番号の選び方
- 最初にアレイを押します5番号はグループとしてグループ化され、最後の5未満は無視されます。数値の各グループを並べ替えて(挿入並べ替えなど)、中央値を見つけます。オン)
- 前のステップからすべての中央値を配列の前に移動し、これらの中央値を繰り返しますBFPRTアルゴリズムを呼び出して、中央値を見つけます。
m = [ 3、2、3 ]の中央値を取得する必要がある場合
は、2番目に
小さい数bfprt(m、2)を見つけます。
- 前のステップで取得した中央値を分割のピボットとして使用して、配列全体を分割します。
public static int bfprt_choose(int[] nums,int m,int n)
{
int l=nums.length%5==0?nums.length/5:nums.length/5+1;
int[] q=new int[l];
int u=0;
for(int i=m;i<=n;i++)
{
if(i+4<=n)
{
q[u]=numsort(nums,i,i+4);
u+=1;
i=i+5;
}
else {
q[u]=numsort(nums,i,n);
}
}
return findk(q, 0, q.length-1, q.length/2);
}
最良の選択はどこですか?
ダンプを修正しました
N 10(中央値)+ 2 ∗ N 10 = 3 N10番号\ frac {N} {10}(中央値)+ 2 * \ frac {N} {10} = \ frac {3N} {10 }番号 1 0N(中位数)+2∗1 0N=1 03 N番号
最悪の複雑さはO(N)です
T(N)= O(N)+ T(N / 5)+ O(3 N / 10)T(N)= O(N)T(N)= O(N)+ T(N / 5)+ O(3N / 10)T(N)= O(N) T (N )=O (N )+T (N / 5 )+O (3 N / 1 0 )T (N )=O (N )
master公式
T(N)= aT(N / b)+ O(N ^ d)
b:
サブプロセスのサンプルサイズa:サブプロセスの計算数
O(N ^ d):サブ結果のマージ
の時間の複雑さ上記の式を満たすすべてのプログラムは、マスター式に従って時間の複雑さを計算できます。
log(b、a)> d:時間の複雑さはO(N ^ log(b、a))
log(b、a)= d:時間の複雑さはO(N ^ d * logN)
log(b、a )<d:時間の複雑さはO(N ^ d)です
アルゴリズムが時代を創る
時間の複雑さの式を直接記述して、アルゴリズムの最終的な時間の式を推測し、このアルゴリズムを検討する価値があるかどうかを確認できます。