リンク:https://zhuanlan.zhihu.com/p/23610451
出典:
著者がほぼ著作権を所有していることを知ってい ます。商用の再版については、著者に連絡して許可を得てください。非商用の再版については、出典を示してください。
最初の3章を勉強した後、自分を抑えることができなかったのはどうですか?放課後の運動に満足していませんか?
今日は週末です。時間がたくさんあります。リートコードをブラッシングしましょう。
リンク
トピック
整数配列と別の整数が与えられた場合、それらの合計が与えられた整数と等しくなるように、配列内の2つの整数を見つけます。これら2つの整数の添え字を返します。
そのような2つの数が常に見つかると仮定すると、結果は一意になります
例
nums = [2、7、11、15]、target = 9の場合
、nums [0] + nums [1] = 2 + 7 = 9である
ため、[0、1]を返します。
問題の意味を理解した後、正式に問題の解決に着手しました。
最初に自分で試してみることをお勧めします。
最初のラウンド
おそらく、考える最も簡単な方法は、2つのループを介してこの問題を解決することです。
外側のループは0からトラバースします:[02、07、11]
内側のループは1から始まります:[07、11、15]
対応する位置の整数の合計が指定された値に等しい場合、添え字が返されます
ページを下にドラッグし、ドロップダウンボックスで「c ++」を選択すると、コーディングを開始できます。
最初に書き込みと読み取りを行い、問題を解決するためのいくつかの方法を考えることをお勧めします。
考えた後、IDEを使用せずにWebサイトで直接コーディングできます。
私はそれをこのように書いた:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> vecResult;
for( int i = 0; i < nums.size() - 1; ++i )
{
for( int j = i + 1; j < nums.size(); ++j )
{
if( nums[i] + nums[j] == target )
{
vecResult.push_back( i );
vecResult.push_back( j );
return vecResult;
}
}
}
return vecResult;
}
};
「コードの実行」をクリックします。そうそう、ワンパスです。「ソリューションの送信」を
クリックして、OK、承認しました。「詳細」をクリックして、なんてことだ、なんてことだ。809msかかりました!ユーザーの5.6%を打ち負かす!360リマインダーの起動速度が全国のユーザーの1%を上回っているのと同じくらい素晴らしいです!!!
注意深く調べてください:
nums.size()は何度も呼び出されていますが、結果を保存するために1回呼び出すとどうなりますか?
OK、
第2ラウンド
「コードの編集」をクリックしてコードを変更します
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> vecResult;
auto iSize = nums.size();
for( int i = 0; i < iSize - 1; ++i )
{
for( int j = i + 1; j < iSize; ++j )
{
if( nums[i] + nums[j] == target )
{
vecResult.push_back( i );
vecResult.push_back( j );
return vecResult;
}
}
}
return vecResult;
}
};
提出後の詳細を見てみましょう、私はそれを拭きました、486ms!ユーザーの33.49%を破った!!!
20パーセントポイント以上増加しました。承認された送信の総数が273,183であることを確認してください。これに50,000以上を掛けたものです。自信が急上昇しました、何もありません!!!
もう一度見てみると、iSize-1は何度も呼び出されていますが、同じ問題です。さて、事前に保存して試してみてください。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> vecResult;
auto iSize = nums.size();
auto iOutterSize = iSize - 1;
for( int i = 0; i < iOutterSize; ++i )
{
for( int j = i + 1; j < iSize; ++j )
{
if( nums[i] + nums[j] == target )
{
vecResult.push_back( i );
vecResult.push_back( j );
return vecResult;
}
}
}
return vecResult;
}
};
提出、たわごと、496ms!なぜもっと時間がかかるのですか?パフォーマンス結果に影響を与えるように一時的な金額を定義することは可能ですか?
一体何が起こっているのか、すべての偉大な神々が私に言うことができますか?
長い間考えていたのですが、考えていなかったので、まずは問題を書き留めました。続けましょう。
この本には、リストの初期化によって配列を初期化できると書かれています。戻り値を変更して、改善できるかどうかを確認しましょう。
OK
第3ラウンド
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
auto iSize = nums.size();
for( int i = 0; i < iSize - 1; ++i )
{
for( int j = i + 1; j < iSize; ++j )
{
if( nums[i] + nums[j] == target )
{
return { i, j };
}
}
}
vector<int> vecResult;
return vecResult;
}
};
499ms?この統計は大丈夫ですか?
しかし、この本は、空のベクトルを作成してから動的に要素を追加することをお勧めしているとも述べています。動的加算の効率は確かに高いようです
return {i、j}を変更して一時的な値を作成し、
vector<int> temp = { i, j };
return temp;
652ms、一時的な金額を作成するには本当に時間がかかります
もちろん、これらは私たちの表面的な説明です。知識を深める前に、それらを書き留めて、将来の調査のために保存しておくことをお勧めします。
他に何を変更できるか考えてみてください。??
シーケンス内の要素にアクセスする方法は3つあります
- の範囲
- 添字
- イテレータ
下付き文字のみを使用しました。範囲は使いにくいです。最初にイテレータを試してみませんか?
第4ラウンド
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> vecResult;
int i = 0;
for( auto itr = nums.begin(); itr != nums.end() - 1; ++itr)
{
int j = i + 1;
for( auto itrInner = itr + 1; itrInner != nums.end(); ++itrInner )
{
if( (*itr) + (*itrInner) == target )
{
vecResult.push_back( i );
vecResult.push_back( j );
return vecResult;
}
++j;
}
++i;
}
return vecResult;
}
};
コードを書くとき、イテレータはこの種の添え字検索には適していないことを知っておく必要があります。
下付き文字を記録するには、2つの変数iとjを定義する必要があります
事実はまったく同じです。コードを送信したとき、大きなデータセットの前で時間がかかりすぎたために拒否されました。
さて、これまでのところ、私たちはそれほど多くしか持っていないようです。
本当か?私が予期していなかった他の方法はありますか?メモを詳しく見てみましょう。
エントリパラメータを変更しようとしたことがありますか?
vector<int> twoSum(const vector<int> &nums, const int &target)
2つのループなしで解決できる解決策はありますか?
本当に理解できない場合は、ディスカッションエリアに移動して、他の人の解決策を確認できます。