You are given two 0-indexed arrays nums1 and nums2 of length n, both of which are permutations of [0, 1, ..., n - 1].
A good triplet is a set of 3 distinct values which are present in increasing order by position both in nums1 and nums2. In other words, if we consider pos1v as the index of the value v in nums1 and pos2v as the index of the value v in nums2, then a good triplet will be a set (x, y, z) where 0 <= x, y, z <= n - 1, such that pos1x < pos1y < pos1z and pos2x < pos2y < pos2z.
Return the total number of good triplets.
Example 1:
Input: nums1 = [2,0,1,3], nums2 = [0,1,2,3] Output: 1 Explanation: There are 4 triplets (x,y,z) such that pos1x < pos1y < pos1z. They are (2,0,1), (2,0,3), (2,1,3), and (0,1,3). Out of those triplets, only the triplet (0,1,3) satisfies pos2x < pos2y < pos2z. Hence, there is only 1 good triplet.
Example 2:
Input: nums1 = [4,0,1,3,2], nums2 = [4,1,0,2,3] Output: 4 Explanation: The 4 good triplets are (4,0,3), (4,0,2), (4,1,3), and (4,1,2).
Constraints:
n == nums1.length == nums2.length3 <= n <= 1050 <= nums1[i], nums2[i] <= n - 1nums1 and nums2 are permutations of [0, 1, ..., n - 1].
class FenwickTree {
private int[] tree;
public FenwickTree(int size) {
tree = new int[size + 1];
}
public void update(int index, int delta) {
index++;
while (index < tree.length) {
tree[index] += delta;
index += index & -index;
}
}
public int query(int index) {
index++;
int res = 0;
while (index > 0) {
res += tree[index];
index -= index & -index;
}
return res;
}
}
class Solution {
public long goodTriplets(int[] nums1, int[] nums2) {
int n = nums1.length;
int[] pos2 = new int[n], reversedIndexMapping = new int[n];
for (int i = 0; i < n; i++) {
pos2[nums2[i]] = i;
}
for (int i = 0; i < n; i++) {
reversedIndexMapping[pos2[nums1[i]]] = i;
}
FenwickTree tree = new FenwickTree(n);
long res = 0;
for (int value = 0; value < n; value++) {
int pos = reversedIndexMapping[value];
int left = tree.query(pos);
tree.update(pos, 1);
int right = (n - 1 - pos) - (value - left);
res += (long) left * right;
}
return res;
}
}
// Brute Force - TLE
// public long goodTriplets(int[] nums1, int[] nums2) {
// int n = nums1.length;
// long ans = 0;
// Map<Integer, Integer> n2 = new HashMap<>();
// for (int i = 0; i < n; i++)
// n2.put(nums2[i], i);
// for (int i = 1; i < n - 1; i++) {
// int i2 = n2.get(nums1[i]);
// int less = 0, more = 0;
// for (int j = i - 1; j >= 0; j--) {
// if (n2.get(nums1[j]) < i2)
// less++;
// }
// for (int j = i + 1; j < n; j++) {
// if (n2.get(nums1[j]) > i2)
// more++;
// }
// ans += less * more;
// }
// return ans;
// }