なぜ、あなたのプログラムがタイムアウト同じアルゴリズムとなっているのですか?あなたは、アルゴリズムコンテストのヒントを知っている必要があります

なぜ、あなたのプログラムがタイムアウト同じアルゴリズムとなっているのですか?あなたは、アルゴリズムコンテストのヒントを知っている必要があります

みなさんこんにちは、私の名前はチー傑(チー関傑)公式で、時間のハエを学習する過程で記録ドリップCSDN、将来は可能で、それを一緒に来る〜


  あなたが頻繁に悩んで、このようなA、なぜ同じアルゴリズムに遭遇していない場合、私は知らない、あなたのプログラムは、タイムアウトとなっていますか?人々はすべてのデータを生きることができるしている理由当社は、大法の暴力を使用していますが、あなただけの最初のいくつかの例を挙げてすることができ、あなたはそんなに遅く、他よりも、なぜ同じことが、DPの使用であり、時には最後の1テスト・ポイントがタイムアウトしています!
  我々は同じ考え、同じアルゴリズムを使用しているが、あなたはこれらの細部におけるアルゴリズムの競争に注意を払っていない場合、それは非常にあなたのプログラムの実行時間を増やす、あるいはあなたのアルゴリズムプログラムの時間計算量が増加しますが、大きさの順序を持ち上げます!以下のブロガーは、あなたがキャッチしていない場合はすぐに見る、いくつかの非常に一般的に使用されるアルゴリズムのゲームいくつかの小さな細部にコンパイル!

ループの決意条件の1機能評価長さ/サイズ

  多くの小規模パートナーは判定条件のように、()ループのために書いたときに、この方法は、変数の長さを書いて保存するように見えるが、それは多くの、より遅いあなたのプログラムを置きます。次の二つのパラグラフの例として、例えば、我々はプログラム:
最初の段落:

#include <iostream>
#include <ctime>
#include <vector>
using namespace std;

int main(){
    vector<int> demo;
    for (int i = 0; i < 100000; ++i) {
        demo.push_back(i);
    }
    int length = demo.size();
    clock_t startTime = clock();
    for (int i = 0; i < length; ++i) {
        demo[i]++;
    }
    clock_t endTime = clock();
    cout<<"执行用时: "<<(endTime - startTime)<<endl;
    return 0;
}
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;

int main(){
    vector<int> demo;
    for (int i = 0; i < 100000; ++i) {
        demo.push_back(i);
    }
    clock_t startTime = clock();
    for (int i = 0; i < demo.size(); ++i) {
        demo[i]++;
    }
    clock_t endTime = clock();
    cout<<"执行用时: "<<(endTime - startTime)<<endl;
    return 0;
}

  それを最初のブロックの出力が内部で実行される执行用时: 401プログラムの第二段階の出力が実行されている执行用时: 278最初のブロックは可変長を使用して、ラインを書くことがあなたは、これら二つの手順を見て、しかし、プログラムは最初の段落でしたプログラムの第二段階よりも効率(非常に高いです这里提高了30%+的效率時々、プログラムが短いと言うことではない、効率が高く、

変数に代入2.マルチユース複雑な数式、

  この状況は非常に一般的であり、多くの場合、我々は、複数の判断、割り当てや他の操作を必要とする複雑な計算、この時間がかかるかもしれません代わりに計算を繰り返すの変数とそれを割り当てるために新しい変数を宣言することに消極的ネヴァー次のコード例:

if(min(max_right[i],max_left[i]) - height[i] > 0)
	ans = ans + min(max_right[i],max_left[i]) - height[i];

次のように我々は、最適化することができます。

int temp = min(max_right[i],max_left[i]) - height[i];
ans += temp > 0 ? temp : 0;

ブロックは同じことを意味しますが、実行効率は、特に、複数の使用中に、たくさんの高い考える必要があります。

「&」より効率的に使用して3パリティ判決

  番号の奇数か偶数かどうかを決定する際に、小さなパートナーの多くが使用する%番号は2で割って見つけることが判断されるべきであり、実際には、ここではそれがあり、より効率的な方法を持っている&場合は、操作してa&1 == 1、それが奇数である、a&1 == 0そして、偶数です。

4.反復の関数に変換することができ、ない書き込み再帰的にしてみてください

  再帰関数を記述するために使用される小さな友人の多くは、再帰関数は、良いプログラムを書く、確かに良いアイデアですが、私たちは時間を持っているとする能力を持っている場合は再帰関数の複雑さは、非常に簡単に出て、非常に大きな時間の複雑さやスペースですそれが良いでしょう、それは時間と空間を節約します、我々はまだ反復を使用し、反復に変換します。

5.スペースのために時間を使うことを学びます

  アルゴリズムにおける競争は、我々は一般的に、多くの場合、制限時間を超えてしまいますが、制限空間のか、非常に少し超えて、一般的なゲームに完全ではないため計上されていても、単にああ、だけでなく、オープンな複数のアレイまで使用16メガバイト256メガバイトであり、数バイトが、このプログラムは、私たちは百倍の時間を節約することができます。例えばそれを書くために昨日ここにタイトルを取る:LeetCode毎日質問42雨水、テキストとコードの特定のトピックを、これを容易にするために、我々は2つのコードを引き継ぐようにした持っています。
コードの最初の部分、暴力に満ち:

class Solution {
public:
    int trap(vector<int>& height) {
        int ans = 0;
        int length = height.size();
        int max_left,max_right;
        for(int i = 0; i< length; i++){
            max_left = max_right = 0;
            //找到左面的最高值
            for(int j = i; j >= 0; j--){
                if(height[j] > max_left)
                    max_left = height[j];
            }
            //找到右面的最高值
            for(int j = i; j < length; j++){
                if(height[j] > max_right)
                    max_right = height[j];
            }
            // 当前柱面能够接的雨水为:左右两名最高值的低值,然后减去当前柱面的高度
            ans += min(max_right,max_left) - height[i];
        }
        return ans;
    }
};

第二段落、最初の段落に基づいて演奏テーブルの使用:

class Solution {
public:
    int trap(vector<int>& height) {
        int ans = 0;
        int length = height.size();
        //空vector时直接返回0
        if(length == 0)
            return 0;
        int max_left[length],max_right[length];
        //i = 0时,左面(含当前)最大值为height[0]
        max_left[0] = height[0];
        for(int i = 1; i < length; i++){
            //max_left[i] 赋值为当前柱面的高度和max_left[i-1]最大值
            max_left[i] = max(height[i],max_left[i-1]);
        }
        //i = length -1 时,右面(含当前)最大值为height[length-1]
        max_right[length-1] = height[length-1];
        for(int i = length-2; i >= 0; i--){
            //max_right[i]赋值为当前柱面的值和max_right[i+1]的最大值
            max_right[i] = max(height[i],max_right[i+1]);
        }
        for(int i = 0; i< length; i++){
            // 当前柱面能够接的雨水为:左右两面最高值的低值,然后减去当前柱面的高度,赋值为temp
            int temp = min(max_right[i],max_left[i]) - height[i];
            // 如果temp>0,则ans进行累加,否则加0
            ans += temp > 0 ? temp : 0;
        }
        return ans;
    }
};

そして、ここで我々は再び両端でのプログラムの実行時間について掲載されているが使用された、第一段階は、416msを使用しています:
ここに画像を挿入説明
2番目の段落は4msのを使用しています:
ここに画像を挿入説明
  プログラムによって使用される時間は、プログラムの2番目の段落の最初の段階で104回、第二段落をプログラムは0.1メガバイトのも、最初のブロックよりもさらに少ないメモリを使用しますが、我々は二つのプログラムの違いを見て、私たちのプログラムの第二段落は、各反復の最初の段落で唯一のプログラムであり、現在のシリンダが探してについてです最高値は、録画した番組の冒頭にアレイを使用して、後でダブルカウントを避けるために。これは、ちょうど2つの小さな配列であり、それはこのエンドプログラムの効率を向上させる104時間を、明らかに時間のためのスペースを使用することがあり、代わりに小さいのプログラムが使用する領域の2番目の段落の結果は、これはとても素晴らしいです!

6. Doが(N ^ 2)最大アルゴリズムOを超えません

  私たちの通常のアルゴリズムコンテストでは、特定の時間計算量はO(n書くとき、時間アルゴリズム2)を、この問題はあなたが十分に冷却することを基本的に、またはあなただけの`ここで(最初の2つの例を取りたいですあなたが考えることができない場合は、ゲームのテストポイントに応じて、言って、最終的には完全に暴力を書くことができ、)ビットが」少しあるごまかすことができます。我々は、一般的には、O(Nまでの時間効率がフィナーレのテーマである場合2)、次いで、O(N)アルゴリズム概して高く、すべての試料は非常に悲しいされているすべてのより悲しい例である、に最適化O必要があるかもしれません保険の前に(LGN)。私たちは、一般的に私たちの荒い時間の複雑さを書くために時間に注意を払うに持っているので、唯一の以前のいくつかの例の後、私は時間の複雑さを最小限に最終結果、プログラムを書くためにあなたの脳をさせてはいけません一般的に上記のヒントの時間を短縮するために使用される5を提供し、あなたが参照できます。彼はすべての主要なソリューションを書いたときの一般的なOで(n)のアルゴリズムは、トレーニング中に、非常に簡単書き出すことですまた、より多くの神の、あなたに新しい問題解決のアイデアを与えるかもしれない参照してください。


さて、ここでは、この問題について、あなたはまた、コメントで共有することができ、他のヒントがああ〜セクション持って

公開された171元の記事 ウォンの賞賛910 ・は 90000 +を見て

おすすめ

転載: blog.csdn.net/qq_43422111/article/details/105326623