Program to find minimum moves to make array complementary in Python


Suppose we have an array nums of even length another value limit. In one move, we can replace any value from nums with another value between 1 and limit, inclusive. The array is said to be complementary if for all indices i, nums[i] + nums[n-1-i] equals the same number. So we have to find the minimum number of moves required to make nums complementary.

So, if the input is like nums = [1,4,2,3] limit = 4, then the output will be 1 because in one move we can make element at index 1 to 2, so array will be [1,2,2,3], then nums[0] + nums[3] = 4, nums[1] + nums[2] = 4, nums[2] + nums[1] = 4, nums[3] + nums[0] = 4

To solve this, we will follow these steps −

  • n := size of nums
  • mid := quotient of n/2
  • zero_moves := an empty map of integer type value
  • start := an array of size (2 * limit + 1), and fill with 0
  • end := an array of size (2 * limit + 1), and fill with 0
  • res := infinity
  • for i in range 0 to mid - 1, do
    • x := nums[i]
    • y := nums[n - 1 - i]
    • zero_moves[x + y] := zero_moves[x + y] + 1
    • increase start[1 + minimum of x, y] by 1
    • increase end[limit + maximum of x, y] by 1
  • intervals := 0
  • for target in range 2 to limit*2, do
    • intervals := intervals + start[target]
    • cost := 2 *(mid - intervals) + intervals - zero_moves[target]
    • res := minimum of res and cost
    • intervals := intervals - end[target]
  • return res

Example

Let us see the following implementation to get better understanding −

from collections import defaultdict
def solve(nums, limit):
   n = len(nums)
   mid = n // 2

   zero_moves = defaultdict(int)

   start = [0] * (2 * limit + 1)
   end = [0] * (2 * limit + 1)
   res = float('inf')
   for i in range(mid):
      x = nums[i]
      y = nums[n - 1 - i]
      zero_moves[x + y] += 1
      start[min(x, y) + 1] += 1
      end[max(x, y) + limit] += 1

   intervals = 0
   for target in range(2, limit * 2 + 1):
      intervals += start[target]
      cost = 2 * (mid - intervals) + intervals - zero_moves[target]
      res = min(res, cost)
      intervals -= end[target]
   return res

nums = [1,4,2,3]
limit = 4
print(solve(nums, limit))

Input

[1,4,2,3], 4

Output

1

Updated on: 05-Oct-2021

217 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements