ワン:概念と分類
コンセプト:
また、時間の複雑さとして知られているプログラムやアルゴリズムの時間効率、複雑
実行統計の数は、固定された操作の数が最も多いという計算の複雑さをランク付けします。
カテゴリー:悪い平均複雑さと複雑さ
注:nの倍数の複雑さと機能の場合、n個のみの関数の最も速い成長の成長に関係
|名前|複雑|
| - | - |
|定数の複雑さ| O(1)|
|対数複雑| O(ログ(N))|
|線形複雑| O(N)|
|多項式複雑| O(n個のk番目のパワー)|
|指数複雑| O(n個のパワー)|
|階乗複雑| O(n)を!|
| |挿入ソート、選択ソート、バブルソート| O(N側)
ソートクイック| |(N *ログ(N-O))|
|バイナリ検索|(Oログ(N))|
II:複雑で計算
問題
1から10000の間で思考番号は、BはAしか答えないことができ、あなたが質問をすることができ、推測するに
yesまたはnoを。
少なくとも、質問の数を推測する方法?
非バイナリ
図1は、ですか?それは2ですか?。。。。それは999ですか?平均500回を依頼します
二分法
500よりも大きいですか?750よりも大きいですか?625よりも大きいですか?憶測の範囲を狭めるためにあらゆる半分は最後だけで10時間を必要とします
バイナリ検索機能
それらが見つからない場合は要素インデックスが、戻り-1が返される検出された場合、書き込み機能BinarySeachは、ルックアップ要素は、大きなAのint配列に小さなPサイズの要素に含まれる。(ログ(N 2 O複雑さの要件を))
BinarySearch
int BinarySearch(int a[],int size,int p)
{
int L=0;//查找区间的左端点
int R=size-1;//查找区间的右端点
while(l<R){//如果查找区间不为空就继续查找
int mid=L+(R-L)/2;//取查找区间正中元素的下标
if (p==a[mid])
return mid;
else if(p>a[mid])
L=mid+1;//设置新的查找区间的左端点
else
R=mid-1;//设置新的查找区间的右端点
}
return -1;
}
int配列aに小から大へ、サイズの要素を含有する発現の要素の小さな整数比機能下界ルックを書きます。
int LowerBound(int a[],int size,int p)//复杂度o(log(n))
{
int L=0;//查找区间的左端点
int R=size-1;//查找区间的右端点
int lastPos=-1;//到目前为止找到的最优解
while(L<R){//如果查找区间不为空就继续查找
int mid=L+(R-L)/2;//取查找区间中元素的下表
if(a[mid]>=p)
R=mid-1;
else{
lastPos=mid;
L=mid+1;
}
}
return lastPos;
}
ご注意ください
注:INT半ば=(L + R )/ 2; // 添え字は中央部要素をとる検索
(L + R)を防止するためには大きすぎるオーバーフローINTミッド= L +(RL)である / 2。
3:二分法は、方程式の根を求めます
問題:
方程式の根の下探している:F(X)= X ^ 3〜5倍^ 2 + 10×80 = 0と、
算出したルート位置A、必要| F()| <= 10 ^ -6;
ソリューション:F(X)の需要伝導方程式Fの根見つけるための公知の二次式により、(X)
導関数0 =無し溶液を、従って導関数ライバル0にf(x)がf(x)が単調増加するように
f(x)が[0.100]が根を有するには、その二分法であると考えられます。
方程式バイナリ方式のルーツを求めて
double EPS=1e-6;
double f(double x){return x*x*x-5*x*x+10*x-80;}
int main(){
double root,x1=0,x2=100,y;
root=x1+(x2-x1)/2;
int triedTimes=1;//记录一共尝试多少次
y=f(root);
while(fabs(y)>EPs){
if(y>0) x2=root;
else x1=root;
root=x1+(x2-x1)/2;
y=f(root);
triedTimes++;
}
printf("%0.8f\n",root);
printf("%d",triedTimes);
return 0;
}
4:ケース:複雑さとアルゴリズムを使用
問題
これらは合計した二つの数字を見つけるために、入力N(N <= 100000)の整数、
整数m(肯定的な可解性を仮定します)。すべての質問は、整数intとして表現することができます
Aソリューション
ダブルループは、すべての負荷方法を列挙し、複雑さは0(N 2)です。
for(int i=0;i<n-1;++i)
for(int j=i+1;j<n;++j)
if(a[i]+a[j]==m)
break;
100 000 * 100000 = 10億円、コミットまたは様々なOJの上のプログラムに参加した
デザインコンペ、この複雑さは確かにタイムアウトします!
ソリューション2
1)ソートアレイ、Oの複雑さ(N- ログ(N))
、我々ができる場合、バイナリサーチMAのアレイ内の各要素[i]の配列2)は、[i]は、参照
を見つけます。複雑ログ(n)は、だけでなく、2のn-最悪の時間を見つけるために、この部分の複雑さのために見た目でもあるので、O(Nログ(N-))
このようなソリューションの複雑さは(N *ログO(N)です )
ソリューション3
1)ソートアレイ、O(Nの複雑ログ(N))
2)時間の検索、初期値は、2つの変数が提供されるi、jは、iが0であり、jは[I]を参照するために、初期値N-1でありますmはせ、Jマイナス1よりも大きい場合には+ [j]は、Mは以下せ以上私はまで1だけインクリメントされている[I] + [J ] = M;
そのような溶液の複雑さはO(N-あるログ( N))
問題
ジョン農夫はNを含む長いストール、(2 <= N <=内蔵 100000)
XN1(0 = .....これらの区画キュービクルの位置はX0、X1である <XI <1000000000、 整数)異なる
Cのジョン(2 <= C <= N)が2頭のいずれかを作成する方法、各州に干渉する、牛、十分に互いに離れ牛肉希望点のヘッド当たり区画に割り当てられました最小距離はできるだけ大きく、最大最小距離の数がそれです。
Aソリューション
....座標X0を取得するにはXN-1を注文した後の最初の区画;
1000000000 / C 1から順番に「最大の最も近い距離D」これをしようとするが、最初の実行可能な答えが見つかりました。:方法試みる
最初の牛X0上1)
XIの最初の牛kは、XI + 1をXN-1に見つかった場合にXJ [1000000000、XI + D]最初に位置する)2
+ K XJの牛の1頭。そのようなXJで、その後、D = D-1)しようとする
すべての牛は、答えはDで、あること、下に置くことができる場合
複雑:10000000000 / C * N、即ち、タイムアウト1000000000
解決策2:
第1の区画の座標X0 .... XN-1所与の順序付けの後
に[L、R]二分法の試み"最大至近距離" D =(L + R) / 2、(Lは、Rが初期値です[ 1,1000000 / C])
Dが実現可能である場合、Dは、新しい[L + R])はL = D + 1(試みるし続けることを覚えておいて
、新しい[L、R]で、Dが不可能な場合(R = D-1)しようとする継続
複雑ログ(1000000000 / C)* N