Computer >> 컴퓨터 >  >> 프로그램 작성 >> Python

Python에서 배열을 보완하기 위한 최소 이동을 찾는 프로그램

<시간/>

다른 값 제한이 짝수인 배열 num이 있다고 가정합니다. 한 번의 이동으로 nums의 값을 1과 limit(포함) 사이의 다른 값으로 바꿀 수 있습니다. 모든 인덱스 i에 대해 nums[i] + nums[n-1-i]가 동일한 숫자이면 배열이 상보적이라고 합니다. 따라서 숫자를 보완하는 데 필요한 최소 이동 수를 찾아야 합니다.

따라서 입력이 nums =[1,4,2,3] limit =4와 같으면 한 번의 이동으로 인덱스 1에서 2까지의 요소를 만들 수 있으므로 출력은 1이 됩니다. 따라서 배열은 [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 :=숫자 크기
  • 중간 :=n/2의 몫
  • zero_moves :=정수 유형 값의 빈 맵
  • start :=크기의 배열(2 * limit + 1), 0으로 채우기
  • end :=크기의 배열(2 * limit + 1), 0으로 채움
  • res :=무한대
  • 0에서 중간 - 1 사이의 i에 대해
    • x :=숫자[i]
    • y :=숫자[n - 1 - i]
    • zero_moves[x + y] :=zero_moves[x + y] + 1
    • 시작[1 + x, y의 최소값]을 1씩 증가
    • 끝[제한 + x, y의 최대값]을 1씩 증가
  • 간격:=0
  • 범위 2에서 제한*2까지의 대상에 대해 다음을 수행합니다.
    • 간격 :=간격 + 시작[대상]
    • 비용:=2 *(중간 - 간격) + 간격 - zero_moves[대상]
    • res :=최소 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