Program to Find the Inverted Inversions in Python


Suppose we have been provided with a list of numbers nums. We have to find the number of existing quadruplets (a, b, c, d) such that a < b < c < d and nums[a] < nums[b] and nums[c] > nums[d].

The array nums is a permutation of the integers 1...N

So, if the input is like nums = [3, 4, 7, 6, 5], then the output will be 5.

From the given input, we have these inverted inversions −

  • 3, 4, 7, 6

  • 3, 4, 6, 5

  • 3, 4, 7, 5

  • 3, 7, 6, 5

  • 4, 7, 6, 5

To solve this, we will follow these steps −

  • m := 10^9 + 7

  • if size of nums < 4, then

    • return 0

  • n := size of nums

  • sorted_ds := a new list

  • Insert the last item of nums in sorted_ds

  • sort the list sorted_ds

  • ds_smaller_than_c := [0] * n

  • for c in range n − 2 to −1, decrease by 1, do

    • ds_smaller_than_c[c] := return the rightmost position in sorted_ds where nums[c] − 1 can be inserted and sorted order can be maintained

    • insert nums[c] at the end of sorted_ds

    • sort the list sorted_ds

  • quadruplet_count := 0

  • sorted_as := a new list

  • insert the first number of nums in sorted_as

  • sort the list sorted_as

  • as_smaller_than_b_sum := 0

  • for b in range 1 to n − 2, do

    • as_smaller_than_b_sum := as_smaller_than_b_sum + the rightmost position in sorted_as where nums[b] – 1 can be inserted and sorted order can be maintained

    • sort the list sorted_as

    • as_smaller_than_b_sum := as_smaller_than_b_sum mod m

    • insert nums[b] at the end of sorted_as

    • sort the list sorted_as

    • quadruplet_count := quadruplet_count + as_smaller_than_b_sum * ds_smaller_than_c[b + 1]

    • quadruplet_count := quadruplet_count mod m

  • return quadruplet_count

Let us see the following implementation to get better understanding −

Example

 Live Demo

import bisect
MOD = 10 ** 9 + 7
class Solution:
   def solve(self, nums):
      if len(nums) < 4:
         return 0
      n = len(nums)
      sorted_ds = list([nums[−1]])
      sorted_ds.sort()
      ds_smaller_than_c = [0] * n
      for c in range(n − 2, −1, −1):
         ds_smaller_than_c[c] = bisect.bisect_right(sorted_ds, nums[c] − 1)
         sorted_ds.append(nums[c])
         sorted_ds.sort()
      quadruplet_count = 0
      sorted_as = list([nums[0]])
      sorted_as.sort()
      as_smaller_than_b_sum = 0
      for b in range(1, n − 2):
         as_smaller_than_b_sum += bisect.bisect_right(sorted_as, nums[b] − 1)
         sorted_as.sort()
         as_smaller_than_b_sum %= MOD
         sorted_as.append(nums[b])
         sorted_as.sort()
         quadruplet_count += as_smaller_than_b_sum * ds_smaller_than_c[b + 1]
         quadruplet_count %= MOD
      return quadruplet_count
ob = Solution()
print(ob.solve([3, 4, 7, 6, 5]))

Input

[3, 4, 7, 6, 5]

Output

5

Updated on: 15-Dec-2020

88 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements