You are given an array target of n integers. From a starting array arr consisting of n 1's, you may perform the following procedure
let x be the sum of all elements currently in your array.
choose index i, such that 0 <= i < n and set the value of arr at index i to x.
You may repeat this procedure as many times as needed.
Return true if it is possible to construct the target array from arr, otherwise, return false.
정수 n개로 이루어진 배열 target이 주어집니다.
처음에는 길이가 n이고 모든 원소가 1인 배열 arr에서 시작합니다.
다음 과정을 원하는 만큼 반복할 수 있습니다.
arr의 모든 원소의 합을 x라고 합니다.i를 하나 선택합니다. 단, 0 <= i < n입니다.arr[i]의 값을 x로 바꿉니다.이 과정을 반복해서 arr을 target 배열과 같게 만들 수 있으면 true를 반환하고, 불가능하면 false를 반환하세요.
입력: target = [9, 3, 5]
출력: true
설명:
처음 배열은 arr = [1, 1, 1]입니다.
[1, 1, 1], 합 = 3, 인덱스 1 선택
[1, 3, 1], 합 = 5, 인덱스 2 선택
[1, 3, 5], 합 = 9, 인덱스 0 선택
[9, 3, 5] 완료
따라서 [1, 1, 1]에서 시작해서 target = [9, 3, 5]를 만들 수 있으므로 true를 반환합니다.
해당 경우에서 가장 늦게 만들어진 수가 뭘까?
왜냐하면 어떤 값을 만들 때는 현재 배열 전체의 합으로 값을 바꾸기 때문이다.
9가 만들어지기 전에는 값들이 어땠을까?
즉 가장 큰 값인 9에서 나머지 값들의 합인 3 + 5를 빼면, 그 자리에 있던 이전 값을 복원할 수 있다.
이 두가지는 빠르게 확인할 수 있겠다.
또한 배열의 길이가 1이고, [1] 이 아닌 경우는 미리 빠르게 False를 리턴할 수 있겠다.
최종적으로 하나 더 빼자면, 나머지 값의 합으로 나머지 연산한 결과값이 0인 경우, 1로만 이루어진 배열로 역연산이 불가능하기에 False를 리턴한다.
from typing import List
from heapq import heapify, heappop, heappush
class MaxHeap:
def __init__(self, arr: List[int]):
self.h = [-v for v in arr]
self.summation = sum(arr)
heapify(self.h)
def pop(self):
target = -heappop(self.h)
self.summation -= target
return target
def push(self, target: int):
self.summation += target
heappush(self.h, -target)
def peek(self):
return -self.h[0]
class Solution:
def isPossible(self, target: List[int]) -> bool:
N = len(target)
if N == 1 and target[0] != 1:
return False
max_h = MaxHeap(target)
while max_h.peek() != 1:
largest = max_h.pop()
if largest <= max_h.summation:
return False
elif max_h.summation == 1:
return True
largest %= max_h.summation
if largest == 0:
return False
max_h.push(largest)
return True