Apr 06, 2022
Edit me
#. Problem
2. My approach
3 for loops for starter, and it shows TLE(Time Limit Error). O(N^3) is 3000 * 3000 * 3000 so makes sense.
Tried with DP, dp[i][j] as counting numbers of i from j to N (3000). Worked, but quite slow.
class Solution {
public:
int threeSumMulti(vector<int>& arr, int target) {
int n = arr.size();
long long ans = 0;
int dp[101][3001];
memset(dp, 0, 101*3001* sizeof(int));
for(int i = arr.size()-1; i >= 0; i--){
for(int idx = 0; idx < 101; idx++){
dp[idx][i] = dp[idx][i+1];
if(idx == arr[i]) dp[idx][i] += 1;
}
}
for(int i = 0; i < n-2; i++){
for(int j = i+1; j < n-1; j++){
int curTarget = target - (arr[i] + arr[j]);
if(curTarget < 0 || curTarget > 100) continue;
ans += dp[curTarget][j+1];
ans %= (long long)1e9+7;
}
}
return ans;
}
};
Time(O(?)) | Space(O(?)) |
---|---|
441 ms | 11.8 MB |
2. Second approach - Map
On the description, it says:
i, j, k such that i < j < k and arr[i] + arr[j] + arr[k] == target.
and this is literally the whole reason of struggles.
It basically means, i != j != k. doesn’t mean that you need to care about index order. Thereby, [1,2,3] and [3,2,1] will show the same result through this algorithm.
With this idea, using unordered map with combination would solve the problem faster.
class Solution {
public:
int threeSumMulti(vector<int>& arr, int target) {
long long ans = 0;
unordered_map<int, int> um;
for(int el : arr){
um[el]++;
}
for(auto el1 : um){
for(auto el2 : um){
int i = el1.first, j = el2.first, k = target-(i+j);
if(!um.count(k)) continue;
long long prevAns = ans;
if(i < j && j < k) ans += (el1.second * el2.second * um[k]);
// nCr = n!/(n-r)!r!
// nC3 = (n * n-1 * n-2) / 3 * 2
if(i == j && j == k) ans += ((long long)el1.second * (el1.second-1) * (el1.second-2))/6;
// nC2 * um[k] = (n * n-1) / 2 * um[k]
if(i == j && j != k) ans += (el1.second * (el1.second - 1)) / 2 * um[k];
if(!(ans - prevAns)) continue;
// cout << i << '+' << j << '+' << k << " = " << ans - prevAns << endl;
ans %= (long long)1e9+7;
}
}
return ans;
}
};
Time(O(N^2)) | Space(O(N)) |
---|---|
12 ms | 10.7 MB |
3. Epilogue
What I’ve learned from this exercise:
- wording is so important sometimes.