leetcodeブラシノート(一、二数の和)
37096 ワード
ずっとleetcodeをブラシしたいと思っていましたが、以前はc言語しかできませんでした.c言語でブラシするのは大変でした.今またコピーを開きました.c++、c++に内蔵されたSTLを勉強した後、leetcodeをブラシするのは簡単でしょう.しかし、いつも自分のアルゴリズムの思考が足りないと感じています.leetcodeをブラシすると自分を向上させることができるでしょう.このテーマは、leetcodeをブラシする過程を記録しています.このテーマを通じて自分にleetcodeを塗って、何か思い出を残したいと思っています.
1.1テーマ
私たちは英語の問題も中国語の問題も来て、ついでに英語を勉強します.
1.1.1 Two Sum
1.1.2両数の和
ソース:力ボタン(LeetCode)リンク:https://leetcode-cn.com/problems/two-sum著作権はインターネットの所有に帰属する.商業転載は公式の授権に連絡してください.非商業転載は出典を明記してください.
正直に言うと、やはり中国語がわかるように見えますが、英語の問題は試しにしてみましょう.
1.2暴力解法
正直に言うと、テーマを見たばかりで、このような方法を考えるしかありません.大神が思っているほど多くはありません.泡の影響が深いかもしれません.いつも2層のforサイクルを考えて、まずプログラムを書いてみましょう.
1.2.1プログラム
1.2.2解析
暴力解法、論理ははっきりしているはずで、両側forは、配列の中の任意の2つの数を組み合わせて、目標値targetと比較して、等しいならば、説明は成功して、待たないならば、循環を続けます.
1.2.3複雑度分析時間複雑度:O(n 2)各要素について,配列の残りの部分を巡回することによって対応するターゲット要素を探すことを試み,O(n)の時間を費やす.従って時間複雑度はO(n 2)である. 空間複雑度:O(1).
1.3 2パスハッシュ表
このような実現は私にも分からないで、問題を解く方法を見た後で、やっと大神がすごいことを理解して、意外にも見て、それでは自分で実現して、良い記憶性は腐った筆頭に及ばないで、1回実現するのはいつも見ているより良いです.
1.3.1プログラム
1.3.2解析
これも比較的簡単で、空間から時間を変える思想で、データを取るのが最も速いのはやはりハッシュ表で、ハッシュ表が1つのデータを取る時間がO(1)なため、しかし適切にメモリを増加しました.
全体思想:1回目の遍歴はvectorの値をハッシュテーブルに保存し、2回目の遍歴は、新しいvectorからデータを取り出し、目標値と減算し、この差を利用してハッシュテーブルにデータを取り、もしなければ、説明が一致していない場合、説明が一致した場合.
1.3.3複雑度分析時間複雑度:O(n)n個の要素を含むリストを2回遍歴した.ハッシュテーブルは検索時間をO(1)に短縮するので,時間複雑度はO(n)である. 空間複雑度:O(n)に必要な余分な空間は、ハッシュテーブルに格納された要素の数に依存し、このテーブルにはn要素が格納されている.
1.4ハッシュ表
1.4.1プログラム
1.4.2解析
このハッシュ表は、よく理解できないかもしれませんが、確かに、昨夜一晩考えて、少し納得したようです.まず、例を書きます.配列要素:2、7、4、11、それから第2の中解法に従ってマッチングします.
2 - 2
2 - 7
2 - 4
2 - 11
7 - 2
7 - 7
7 - 4
7 - 11
4 - 2
4 - 7
4 - 4
4 - 11
11 - 2
11 - 7
11 - 4
11 - 11
上の表は、すべてのマッチング状況をリストしています.目の先の友达ではありませんか.対称の関係を見ています.間違いありません.実は、この表は対角線対称です.つまり、少なくとも2つの検索が重複しています.また、2つの下のマークも同じです.削除します.だから、重複を削除します.
2 - 2
2 - 7
2 - 4
2 - 11
7 - 2
7 - 7
7 - 4
7 - 11
4 - 2
4 - 7
4 - 4
4 - 11
11 - 2
11 - 7
11 - 4
11 - 11
このように削除した後、いくつかの不思議な現象を発見したのではないでしょうか.このような表に従って、1回のマッチングを挿入することをサポートします.は2をハッシュテーブルに挿入し、一致し、一致しなかった. は、ハッシュ・テーブルに7を挿入し、マッチングする(7−2). は、4をハッシュ・テーブルに挿入し、マッチングする(4−2、4−7). は、11をハッシュテーブルに挿入し、その後、一致する(11-2、11-7、11-4) 表の中のものを全部一致させたのではないでしょうか.
1.4.3複雑度分析時間複雑度:O(n)n個の要素を含むリストを1回だけ巡回した.テーブルでの検索にはO(1)の時間しかかかりません. 空間複雑度:O(n)に必要な余分な空間は、ハッシュ・テーブルに格納されている要素の数に依存し、このテーブルには最大n要素を格納する必要がある.
私もこのような考えが正しいかどうか分かりません.もし間違っていたら、討論を歓迎して、勉強して、一緒に討論します.
テストの結果,要素が同じであることもハッシュテーブルで判断できる.
1.1テーマ
私たちは英語の問題も中国語の問題も来て、ついでに英語を勉強します.
1.1.1 Two Sum
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
1.1.2両数の和
nums target, , 。
。 , 。
:
nums = [2, 7, 11, 15], target = 9
nums[0] + nums[1] = 2 + 7 = 9
[0, 1]
ソース:力ボタン(LeetCode)リンク:https://leetcode-cn.com/problems/two-sum著作権はインターネットの所有に帰属する.商業転載は公式の授権に連絡してください.非商業転載は出典を明記してください.
正直に言うと、やはり中国語がわかるように見えますが、英語の問題は試しにしてみましょう.
1.2暴力解法
正直に言うと、テーマを見たばかりで、このような方法を考えるしかありません.大神が思っているほど多くはありません.泡の影響が深いかもしれません.いつも2層のforサイクルを考えて、まずプログラムを書いてみましょう.
1.2.1プログラム
/*
nums target, ,
。
。 , 。
:
nums = [2, 7, 11, 15], target = 9
nums[0] + nums[1] = 2 + 7 = 9
[0, 1]
*/
#include
#include
using namespace std;
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> temp;
//1.
int i = 0, j = 0;
for(i=0; i<nums.size(); i++) {
for(j=i+1; j<nums.size(); j++) {
if(nums[i] + nums[j] == target) {
cout << " , vector " << endl;
cout << nums[i] << " "<< nums[j] << endl;
temp.push_back(i);
temp.push_back(j);
}
}
}
return temp;
}
};
int main(int argc, char** argv)
{
int array[] = {2, 7, 11, 15};
vector<int> nums(array, array+sizeof(array)/sizeof(int));
int target = 9;
Solution p;
p.twoSum(nums, target);
return 0;
}
1.2.2解析
暴力解法、論理ははっきりしているはずで、両側forは、配列の中の任意の2つの数を組み合わせて、目標値targetと比較して、等しいならば、説明は成功して、待たないならば、循環を続けます.
1.2.3複雑度分析
1.3 2パスハッシュ表
このような実現は私にも分からないで、問題を解く方法を見た後で、やっと大神がすごいことを理解して、意外にも見て、それでは自分で実現して、良い記憶性は腐った筆頭に及ばないで、1回実現するのはいつも見ているより良いです.
1.3.1プログラム
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> temp;
int i = 0, j = 0;
//1.
#if 0
for(i=0; i<nums.size(); i++) {
for(j=i+1; j<nums.size(); j++) {
if(nums[i] + nums[j] == target) {
cout << " , vector " << endl;
cout << nums[i] << " "<< nums[j] << endl;
temp.push_back(i);
temp.push_back(j);
}
}
}
#endif
//2.
//unordered_map c++
unordered_map<int, int> hash_map;
//
for(i=0; i<nums.size(); i++) {
//hash_map.insert(make_pair(1, 1));
hash_map.insert(pair<int, int>(nums[i], i));
}
// vector ,
for(i=0; i<nums.size(); i++) {
cout << target - nums[i] << endl;
unordered_map<int,int>::const_iterator got = hash_map.find(target - nums[i]);
if(got != hash_map.end() && i != got->second) {
//
cout << i << " " << got->second << endl;
temp.push_back(i);
temp.push_back(got->second);
return temp;
}
}
return temp;
}
};
1.3.2解析
これも比較的簡単で、空間から時間を変える思想で、データを取るのが最も速いのはやはりハッシュ表で、ハッシュ表が1つのデータを取る時間がO(1)なため、しかし適切にメモリを増加しました.
全体思想:1回目の遍歴はvectorの値をハッシュテーブルに保存し、2回目の遍歴は、新しいvectorからデータを取り出し、目標値と減算し、この差を利用してハッシュテーブルにデータを取り、もしなければ、説明が一致していない場合、説明が一致した場合.
1.3.3複雑度分析
1.4ハッシュ表
1.4.1プログラム
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> temp;
int i = 0, j = 0;
//1.
#if 0
for(i=0; i<nums.size(); i++) {
for(j=i+1; j<nums.size(); j++) {
if(nums[i] + nums[j] == target) {
cout << " , vector " << endl;
cout << nums[i] << " "<< nums[j] << endl;
temp.push_back(i);
temp.push_back(j);
}
}
}
#endif
//2.
#if 0
//unordered_map c++
unordered_map<int, int> hash_map;
//
for(i=0; i<nums.size(); i++) {
//hash_map.insert(make_pair(1, 1));
hash_map.insert(pair<int, int>(nums[i], i));
}
// vector ,
for(i=0; i<nums.size(); i++) {
cout << target - nums[i] << endl;
unordered_map<int,int>::const_iterator got = hash_map.find(target - nums[i]);
if(got != hash_map.end() && i != got->second) {
cout << i << " " << got->second << endl;
temp.push_back(i);
temp.push_back(got->second);
return temp;
}
}
#endif
//3.
unordered_map<int, int> hash_map;
for(i=0; i<nums.size(); i++) {
cout << target - nums[i] << endl;
//
unordered_map<int,int>::const_iterator got = hash_map.find(target - nums[i]);
if(got != hash_map.end()) {
cout << i << " " << got->second << endl;
temp.push_back(i);
temp.push_back(got->second);
return temp;
}
// ,
hash_map.insert(pair<int, int>(nums[i], i));
}
return temp;
}
};
1.4.2解析
このハッシュ表は、よく理解できないかもしれませんが、確かに、昨夜一晩考えて、少し納得したようです.まず、例を書きます.配列要素:2、7、4、11、それから第2の中解法に従ってマッチングします.
2 - 2
2 - 7
2 - 4
2 - 11
7 - 2
7 - 7
7 - 4
7 - 11
4 - 2
4 - 7
4 - 4
4 - 11
11 - 2
11 - 7
11 - 4
11 - 11
上の表は、すべてのマッチング状況をリストしています.目の先の友达ではありませんか.対称の関係を見ています.間違いありません.実は、この表は対角線対称です.つまり、少なくとも2つの検索が重複しています.また、2つの下のマークも同じです.削除します.だから、重複を削除します.
2 - 2
2 - 7
2 - 4
2 - 11
7 - 2
7 - 7
7 - 4
7 - 11
4 - 2
4 - 7
4 - 4
4 - 11
11 - 2
11 - 7
11 - 4
11 - 11
このように削除した後、いくつかの不思議な現象を発見したのではないでしょうか.このような表に従って、1回のマッチングを挿入することをサポートします.
1.4.3複雑度分析
私もこのような考えが正しいかどうか分かりません.もし間違っていたら、討論を歓迎して、勉強して、一緒に討論します.
テストの結果,要素が同じであることもハッシュテーブルで判断できる.