|
| 1 | +class Solution: |
| 2 | + def goodTriplets(self, nums1, nums2): |
| 3 | + """ |
| 4 | + Intuition: |
| 5 | + We want to count how many triplets (i < j < k) exist such that |
| 6 | + nums1[i], nums1[j], nums1[k] appear in the same order in nums2. |
| 7 | +
|
| 8 | + So, if we convert nums1 to the index order of nums2, the problem becomes: |
| 9 | + -> Count the number of increasing triplets in the new index list. |
| 10 | +
|
| 11 | + Approach: |
| 12 | + - First, find out where each value in nums2 appears (its position). |
| 13 | + - Then, replace each value in nums1 with its index in nums2. |
| 14 | + - Now we want to count how many smaller elements are on the left |
| 15 | + and how many bigger elements are on the right for each index. |
| 16 | + - We do this using a Fenwick Tree (Binary Indexed Tree). |
| 17 | +
|
| 18 | + Complexity: |
| 19 | + Time: O(n log n) because each update/query in Fenwick Tree takes log n time. |
| 20 | + Space: O(n) for extra arrays and the tree. |
| 21 | + """ |
| 22 | + |
| 23 | + def update(tree, index, value): |
| 24 | + # Add 'value' to index in tree |
| 25 | + while index < len(tree): |
| 26 | + tree[index] += value |
| 27 | + index += index & -index # Move to next responsible index |
| 28 | + |
| 29 | + def query(tree, index): |
| 30 | + # Get prefix sum from 1 to index |
| 31 | + result = 0 |
| 32 | + while index > 0: |
| 33 | + result += tree[index] |
| 34 | + index -= index & -index # Move to parent |
| 35 | + return result |
| 36 | + |
| 37 | + n = len(nums1) |
| 38 | + |
| 39 | + # Step 1: Create a map from number to its index in nums2 |
| 40 | + # So we can know where each number is located in nums2 |
| 41 | + position = {} |
| 42 | + for i in range(n): |
| 43 | + position[nums2[i]] = i |
| 44 | + |
| 45 | + # Step 2: Convert nums1 into positions from nums2 |
| 46 | + # Now we just work with index values |
| 47 | + index_list = [] |
| 48 | + for num in nums1: |
| 49 | + index_list.append(position[num]) |
| 50 | + |
| 51 | + # Step 3: Count how many smaller values are to the left of each index |
| 52 | + # Fenwick Tree needs to be size n+2 because we work with 1-based index |
| 53 | + size = n + 2 |
| 54 | + left_tree = [0] * size |
| 55 | + left_count = [0] * n |
| 56 | + |
| 57 | + for i in range(n): |
| 58 | + idx = index_list[i] + 1 # shift for 1-based BIT |
| 59 | + # Count of numbers smaller than current on the left |
| 60 | + left_count[i] = query(left_tree, idx - 1) |
| 61 | + update(left_tree, idx, 1) |
| 62 | + |
| 63 | + # Step 4: Count how many bigger values are to the right of each index |
| 64 | + right_tree = [0] * size |
| 65 | + right_count = [0] * n |
| 66 | + |
| 67 | + for i in range(n - 1, -1, -1): |
| 68 | + idx = index_list[i] + 1 |
| 69 | + # Count of numbers bigger than current on the right |
| 70 | + right_count[i] = query(right_tree, n + 1) - query(right_tree, idx) |
| 71 | + update(right_tree, idx, 1) |
| 72 | + |
| 73 | + # Step 5: Multiply counts to get total number of good triplets |
| 74 | + total = 0 |
| 75 | + for i in range(n): |
| 76 | + total += left_count[i] * right_count[i] |
| 77 | + |
| 78 | + return total |
0 commit comments