Skip to content

Commit 80ad10a

Browse files
committed
2179
1 parent 259b79a commit 80ad10a

File tree

2 files changed

+134
-0
lines changed

2 files changed

+134
-0
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1802,6 +1802,10 @@ Now I'm using a Chrome Extension I developed -- [LeetCoder](https://chrome.googl
18021802
2170 | Minimum Operations to Make the Array Alternating | Medium | [Solution](leetcode/2170.%20Minimum%20Operations%20to%20Make%20the%20Array%20Alternating)
18031803
2171 | Removing Minimum Number of Magic Beans | Medium | [Solution](leetcode/2171.%20Removing%20Minimum%20Number%20of%20Magic%20Beans)
18041804
2172 | Maximum AND Sum of Array | Hard | [Solution](leetcode/2172.%20Maximum%20AND%20Sum%20of%20Array)
1805+
2176 | Count Equal and Divisible Pairs in an Array | Easy | [Solution](leetcode/2176.%20Count%20Equal%20and%20Divisible%20Pairs%20in%20an%20Array)
1806+
2177 | Find Three Consecutive Integers That Sum to a Given Number | Medium | [Solution](leetcode/2177.%20Find%20Three%20Consecutive%20Integers%20That%20Sum%20to%20a%20Given%20Number)
1807+
2178 | Maximum Split of Positive Even Integers | Medium | [Solution](leetcode/2178.%20Maximum%20Split%20of%20Positive%20Even%20Integers)
1808+
2179 | Count Good Triplets in an Array | Hard | [Solution](leetcode/2179.%20Count%20Good%20Triplets%20in%20an%20Array)
18051809

18061810

18071811
# FAQ
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# [2179. Count Good Triplets in an Array (Hard)](https://leetcode.com/problems/count-good-triplets-in-an-array/)
2+
3+
<p>You are given two <strong>0-indexed</strong> arrays <code>nums1</code> and <code>nums2</code> of length <code>n</code>, both of which are <strong>permutations</strong> of <code>[0, 1, ..., n - 1]</code>.</p>
4+
5+
<p>A <strong>good triplet</strong> is a set of <code>3</code> <strong>distinct</strong> values which are present in <strong>increasing order</strong> by position both in <code>nums1</code> and <code>nums2</code>. In other words, if we consider <code>pos1<sub>v</sub></code> as the index of the value <code>v</code> in <code>nums1</code> and <code>pos2<sub>v</sub></code> as the index of the value <code>v</code> in <code>nums2</code>, then a good triplet will be a set <code>(x, y, z)</code> where <code>0 &lt;= x, y, z &lt;= n - 1</code>, such that <code>pos1<sub>x</sub> &lt; pos1<sub>y</sub> &lt; pos1<sub>z</sub></code> and <code>pos2<sub>x</sub> &lt; pos2<sub>y</sub> &lt; pos2<sub>z</sub></code>.</p>
6+
7+
<p>Return <em>the <strong>total number</strong> of good triplets</em>.</p>
8+
9+
<p>&nbsp;</p>
10+
<p><strong>Example 1:</strong></p>
11+
12+
<pre><strong>Input:</strong> nums1 = [2,0,1,3], nums2 = [0,1,2,3]
13+
<strong>Output:</strong> 1
14+
<strong>Explanation:</strong>
15+
There are 4 triplets (x,y,z) such that pos1<sub>x</sub> &lt; pos1<sub>y</sub> &lt; pos1<sub>z</sub>. They are (2,0,1), (2,0,3), (2,1,3), and (0,1,3).
16+
Out of those triplets, only the triplet (0,1,3) satisfies pos2<sub>x</sub> &lt; pos2<sub>y</sub> &lt; pos2<sub>z</sub>. Hence, there is only 1 good triplet.
17+
</pre>
18+
19+
<p><strong>Example 2:</strong></p>
20+
21+
<pre><strong>Input:</strong> nums1 = [4,0,1,3,2], nums2 = [4,1,0,2,3]
22+
<strong>Output:</strong> 4
23+
<strong>Explanation:</strong> The 4 good triplets are (4,0,3), (4,0,2), (4,1,3), and (4,1,2).
24+
</pre>
25+
26+
<p>&nbsp;</p>
27+
<p><strong>Constraints:</strong></p>
28+
29+
<ul>
30+
<li><code>n == nums1.length == nums2.length</code></li>
31+
<li><code>3 &lt;= n &lt;= 10<sup>5</sup></code></li>
32+
<li><code>0 &lt;= nums1[i], nums2[i] &lt;= n - 1</code></li>
33+
<li><code>nums1</code> and <code>nums2</code> are permutations of <code>[0, 1, ..., n - 1]</code>.</li>
34+
</ul>
35+
36+
37+
**Similar Questions**:
38+
* [Count of Smaller Numbers After Self (Hard)](https://leetcode.com/problems/count-of-smaller-numbers-after-self/)
39+
* [Increasing Triplet Subsequence (Medium)](https://leetcode.com/problems/increasing-triplet-subsequence/)
40+
* [Create Sorted Array through Instructions (Hard)](https://leetcode.com/problems/create-sorted-array-through-instructions/)
41+
42+
## Solution 1. Divide and Conquer (Merge Sort)
43+
44+
45+
The first idea is that we pick a number as the middle number in the triplet, and count the common numbers in front of this number and after this number.
46+
47+
For example,
48+
49+
```
50+
A = [4,0,1,3,2]
51+
B = [4,1,0,2,3]
52+
```
53+
54+
For number `1`, there is a single common number (`4`) in front of `1` and two common numbers (`3,4`) after `1`, so the count of triplets with `1` in the middle is `1 * 2 = 2`.
55+
56+
But counting the common numbers is not easy. **Since the numbers are permutations of `[0, N-1]`, we can simplify the problem by mapping on of the array to `[0, N-1]`.**
57+
58+
For example, if we map `A` to `[0, N-1]`.
59+
60+
```
61+
A = [4,0,1,3,2]
62+
A'= [0,1,2,3,4]
63+
mapping = 4->0, 0->1, 1->2, 3->3, 2->4
64+
```
65+
66+
We apply the same mapping to `B`
67+
68+
```
69+
B = [4,1,0,2,3]
70+
B'= [0,2,1,4,3]
71+
```
72+
73+
Now look at the new arrays
74+
75+
```
76+
A = [0,1,2,3,4]
77+
B = [0,2,1,4,3]
78+
```
79+
80+
For the number `1`, we trivially know that in `A`, there is one number `0` before it and 3 numbers `2,3,4` after it. So, we just need to look at `B`. The problem now becomes counting the numbers smaller than `1` before `1` and numbers greater than `1` after `1`.
81+
82+
Let `lt[i]` be the count of numbers smaller than `B[i]`. The count of common numbers before `B[i]` is `min(B[i], lt[i])`. The count of common numbers after `B[i]` in `A` is `N - B[i] - 1`. The count of common numbers after `B[i]` in `B` is `N - i - 1 - (B[i] - lt[i]) = N - B[i] - 1 - i + lt[i]`. Since `i >= lt[i]`, `-i + lt[i] <= 0`, the count of common numbers after `B[i]` in both arrays is `N - B[i] - 1 - i + lt[i]`.
83+
84+
So, the count of triplets with `B[i]` as the middle number is `min(B[i], lt[i]) * (N - B[i] - 1 - i + lt[i])`
85+
86+
```cpp
87+
// OJ: https://leetcode.com/problems/count-good-triplets-in-an-array/
88+
// Author: github.com/lzl124631x
89+
// Time: O(NlogN)
90+
// Space: O(N)
91+
class Solution {
92+
public:
93+
long long goodTriplets(vector<int>& A, vector<int>& B) {
94+
long N = A.size(), ans = 0;
95+
vector<int> m(N), lt(N), tmp(N), tmpLt(N), index(N);
96+
for (int i = 0; i < N; ++i) m[A[i]] = i;
97+
for (int i = 0; i < N; ++i) {
98+
B[i] = m[B[i]];
99+
index[B[i]] = i;
100+
}
101+
function<void(int, int)> merge = [&](int begin, int end) {
102+
if (begin + 1 >= end) return;
103+
int mid = (begin + end) / 2;
104+
merge(begin, mid);
105+
merge(mid, end);
106+
int i = begin, j = mid, k = begin;
107+
for (; k < end; ++k) {
108+
if (j >= end || (i < mid && B[i] < B[j])) {
109+
tmp[k] = B[i];
110+
tmpLt[k] = lt[i];
111+
++i;
112+
} else {
113+
tmp[k] = B[j];
114+
tmpLt[k] = lt[j] + i - begin;
115+
++j;
116+
}
117+
}
118+
for (int i = begin; i < end; ++i) {
119+
B[i] = tmp[i];
120+
lt[i] = tmpLt[i];
121+
}
122+
};
123+
merge(0, N);
124+
for (int i = 0; i < N; ++i) {
125+
ans += (long)min(B[i], lt[i]) * (N - B[i] - 1 - index[B[i]] + lt[i]);
126+
}
127+
return ans;
128+
}
129+
};
130+
```

0 commit comments

Comments
 (0)