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

Python에서 가장 가까운 부분 수열 합을 찾는 프로그램

<시간/>

배열 num과 다른 값 목표가 있다고 가정합니다. 요소의 합이 목표에 가장 가깝도록 nums의 하위 시퀀스를 선택하려고 합니다. 즉, 하위 시퀀스 요소의 합이 s이면 절대 차이 |s - 목표|를 최소화하려고 합니다.

따라서 우리는 |s - 목표|의 가능한 최소 값을 찾아야 합니다. 따라서 입력이 nums =[8,-8,16,-1] 목표 =-3과 같으면 출력은 2가 됩니다. 합이 -1인 하위 시퀀스 [8,-8,-1]입니다. 절대 차이는 |-1 - (-3)| =abs(2) =2, 이것은 최소값입니다.

이 문제를 해결하기 위해 다음 단계를 따릅니다. −

  • n :=숫자 크기

  • x의 절대값을 얻은 후 -ve 값을 기준으로 숫자 정렬

  • neg :=n+1 크기의 배열을 만들고 0으로 채움

  • pos :=n+1 크기의 배열을 만들고 0으로 채움

  • n-1 ~ 0 범위의 i에 대해 1 감소, 수행

    • nums[i] <0이면

      • 음수[i] :=음수[i+1] + 숫자[i]

      • pos[i] :=pos[i+1]

    • 그렇지 않으면

      • 위치[i] :=위치[i+1] + 숫자[i]

      • 부정[i] :=부정[i+1]

  • 답변 :=|목표|

  • s :=0을 삽입하는 새 세트

  • check() 함수를 정의합니다. 이것은, b

  • b <목표 - ans 또는 목표 + as

    • 거짓을 반환

  • 참을 반환

  • 기본 방법에서 다음을 수행하십시오.

  • 범위 0에서 n - 1에 있는 i에 대해 수행

    • sl :=check(x+neg[i], x+pos[i]가 true일 때 s의 모든 x에 대한 x 목록]

    • sl의 크기가 0과 같으면

      • 루프에서 나오다

    • s :=sl의 새로운 세트

    • sl의 각 x에 대해 수행

      • y :=x + 숫자[i]

      • 만약 |y - 목표| <그럼

        • as :=|y - 목표|

      • as가 0과 같으면

        • 0 반환

      • s에 y를 삽입

  • 반환

예시

이해를 돕기 위해 다음 구현을 살펴보겠습니다.

from collections import Counter
def solve(nums, goal):
   n = len(nums)
   nums.sort(key=lambda x: -abs(x))
   neg = [0 for _ in range(n+1)]
   pos = [0 for _ in range(n+1)]
   for i in range(n-1, -1, -1):
      if nums[i] < 0:
         neg[i] = neg[i+1] + nums[i]
         pos[i] = pos[i+1]
      else:
         pos[i] = pos[i+1] + nums[i]
         neg[i] = neg[i+1]
   ans = abs(goal)
   s = set([0])
   def check(a, b):
      if b < goal - ans or goal + ans < a:
         return False
      return True
   for i in range(n):
      sl = [x for x in s if check(x+neg[i], x+pos[i])]
      if len(sl) == 0:
         break
      s = set(sl)
      for x in sl:
         y = x + nums[i]
         if abs(y - goal) < ans:
            ans = abs(y - goal)
         if ans == 0:
            return 0
         s.add(y)
   return ans

nums = [8,-8,16,-1]
goal = -3
print(solve(nums, goal))

입력

[0,1,2,3,4], [[3,1],[1,3],[5,6]]

출력

2