Welcome to Subscribe On Youtube
2179. Count Good Triplets in an Array
Description
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.length
3 <= n <= 105
0 <= nums1[i], nums2[i] <= n - 1
nums1
andnums2
are permutations of[0, 1, ..., n - 1]
.
Solutions
Binary Indexed Tree or Segment Tree.
-
class Solution { public long goodTriplets(int[] nums1, int[] nums2) { int n = nums1.length; int[] pos = new int[n]; BinaryIndexedTree tree = new BinaryIndexedTree(n); for (int i = 0; i < n; ++i) { pos[nums2[i]] = i + 1; } long ans = 0; for (int num : nums1) { int p = pos[num]; long left = tree.query(p); long right = n - p - (tree.query(n) - tree.query(p)); ans += left * right; tree.update(p, 1); } return ans; } } class BinaryIndexedTree { private int n; private int[] c; public BinaryIndexedTree(int n) { this.n = n; c = new int[n + 1]; } public void update(int x, int delta) { while (x <= n) { c[x] += delta; x += lowbit(x); } } public int query(int x) { int s = 0; while (x > 0) { s += c[x]; x -= lowbit(x); } return s; } public static int lowbit(int x) { return x & -x; } }
-
class BinaryIndexedTree { public: int n; vector<int> c; BinaryIndexedTree(int _n) : n(_n) , c(_n + 1) {} void update(int x, int delta) { while (x <= n) { c[x] += delta; x += lowbit(x); } } int query(int x) { int s = 0; while (x > 0) { s += c[x]; x -= lowbit(x); } return s; } int lowbit(int x) { return x & -x; } }; class Solution { public: long long goodTriplets(vector<int>& nums1, vector<int>& nums2) { int n = nums1.size(); vector<int> pos(n); for (int i = 0; i < n; ++i) pos[nums2[i]] = i + 1; BinaryIndexedTree* tree = new BinaryIndexedTree(n); long long ans = 0; for (int& num : nums1) { int p = pos[num]; int left = tree->query(p); int right = n - p - (tree->query(n) - tree->query(p)); ans += 1ll * left * right; tree->update(p, 1); } return ans; } };
-
class BinaryIndexedTree: def __init__(self, n): self.n = n self.c = [0] * (n + 1) @staticmethod def lowbit(x): return x & -x def update(self, x, delta): while x <= self.n: self.c[x] += delta x += BinaryIndexedTree.lowbit(x) def query(self, x): s = 0 while x > 0: s += self.c[x] x -= BinaryIndexedTree.lowbit(x) return s class Solution: def goodTriplets(self, nums1: List[int], nums2: List[int]) -> int: pos = {v: i for i, v in enumerate(nums2, 1)} ans = 0 n = len(nums1) tree = BinaryIndexedTree(n) for num in nums1: p = pos[num] left = tree.query(p) right = n - p - (tree.query(n) - tree.query(p)) ans += left * right tree.update(p, 1) return ans
-
type BinaryIndexedTree struct { n int c []int } func newBinaryIndexedTree(n int) *BinaryIndexedTree { c := make([]int, n+1) return &BinaryIndexedTree{n, c} } func (this *BinaryIndexedTree) lowbit(x int) int { return x & -x } func (this *BinaryIndexedTree) update(x, delta int) { for x <= this.n { this.c[x] += delta x += this.lowbit(x) } } func (this *BinaryIndexedTree) query(x int) int { s := 0 for x > 0 { s += this.c[x] x -= this.lowbit(x) } return s } func goodTriplets(nums1 []int, nums2 []int) int64 { n := len(nums1) pos := make([]int, n) for i, v := range nums2 { pos[v] = i + 1 } tree := newBinaryIndexedTree(n) var ans int64 for _, num := range nums1 { p := pos[num] left := tree.query(p) right := n - p - (tree.query(n) - tree.query(p)) ans += int64(left) * int64(right) tree.update(p, 1) } return ans }