在Python中找到使数组互补的最小移动次数的程序

在Python中找到使数组互补的最小移动次数的程序

假设我们有一个长度为偶数的数组nums和另一个值limit。在一次移动中,我们可以将nums中的任何值替换为另一个值,该值位于1到limit之间(含limit)。如果对于所有索引i,nums[i] + nums[n-1-i]等于相同的数字,则该数组被称为互补。因此,我们必须找到使nums互补所需的最小移动次数。

因此,如果输入如下nums = [1,4,2,3] limit = 4,则输出将为1,因为我们可以在一次移动中将索引1处的元素更改为2,因此数组将为[1,2,2,3],那么nums[0] + nums[3] = 4,nums[1] + nums[2] = 4,nums[2] + nums[1] = 4,nums[3] + nums[0] = 4

要解决此问题,我们将遵循以下步骤:

  • n := nums的大小
  • mid := n/2的商
  • zero_moves :=整数类型值的空映射
  • start :=大小为(2*limit + 1)的数组,并用0填充
  • end :=大小为(2*limit + 1)的数组,并用0填充
  • res :=无限大数值
  • 对于i在range 0到mid – 1中,执行以下操作:
    • x := nums[i]
    • y := nums[n – 1 – i]
    • zero_moves[x + y] := zero_moves[x + y] + 1
    • 将start[最小值(x,y) + 1]增加1
    • 将end[最大值(x,y) + limit]增加1
  • intervals := 0
  • 对于目标在range 2到limit * 2中,执行以下操作:
    • intervals :=intervals + start[target]
    • cost := 2*(mid – intervals)+ intervals – zero_moves[target]
    • res :=res和cost的最小值
    • intervals :=intervals – end[target]
  • 返回res

示例

让我们看一下以下实现,以更好地理解−

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))

输入

[1,4,2,3], 4

输出

1

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程