問題の説明:
4 A、B、C、D、計算どのように多くのタプルのリストを含む整数の配列を指定(i, j, k, l)
ように A[i] + B[j] + C[k] + D[l] = 0
。
問題を簡単にするために、A、B、C、Dの全てが同じ長さN、および0≤N≤500を有しています。-228 1〜228--の範囲のすべての整数は、最終的な結果は231--1を超えません。
例えば:
入力: A = [1、2] B = [-2、-1] C = [-1、2] D = [0,2] 出力: 2 説明: 次の2つの元のグループであった: 1(0,0 、0 ,. 1) - > A [0] + B [0] + C [0] + D + 1 =(-2)+(-1)2 + 0 = [1]。 2(1 ,. 1,0。 、0) - > A [1 ] + B [1] + C [0] + D [0] = 2 +(-1)+(-1)+ 0 = 0
基本的な考え方:
この質問の暴力はO(n ^ 4)は、絶対に望ましくありません。だから、二部スキル。
最初の二つのリストを横断し、2つの数の全てを取得、二つのリストを横断した後、すべての数字をと2を取得し、双方の互いの逆数の要素の結果セットの数の統計は、答えです。
だから、我々は(N ^ 2)Oへの複雑さを軽減しました。
しかし、まだTLEは、私たちは、複雑さを軽減するために思考ハッシュテーブルで思いました。
ハッシュテーブルからである挿入とクエリ素子平均時間の複雑性は、O(1)です。
(例えばBSTのようなその他、挿入とクエリはO(LOGN)、通常のベクター、挿入O(1)の際に、クエリO(N)です)
同時に、我々はできるコード要素とクエリを取得するための即時の道の量を減らします。
ACコード:
class Solution {
public:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
// 二分法降低复杂度
// 使用hashmap代表多重集,(合并处理和查询)降低查询时间复杂度
int n = A.size();
// 个人认为m是value_initialized的理由是一开始没法初始化
unordered_map<int, int> m; // 第一个元素代表元素值,第二个元素代表重复的次数
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
++m[A[i] + B[j]];
}
}
int count = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
count += m[-C[i] - D[j]];
}
}
return count;
}
};
その他の経験:
- 私は、右の息子はまだ非常に合理的であると言っている地図は、実際にunordered_mapよりもはるかに遅いです。
- 私たちがした場合、複数のセットを使用する必要がある、あなたはunorder_map使用してシミュレートすることができ、それに対応するキーの値は、要素の繰り返しの数です。
- 後処理要素が一致する場合は、通過することができる複雑さを軽減するために側端整合アプローチを介し。