Construct Target Array With Multiple Sums (H)
题目
Given an array of integers target
. From a starting array, A
consisting of all 1's, you may perform the following procedure :
- let
x
be the sum of all elements currently in your array. - choose index
i
, such that0 <= i < target.size
and set the value ofA
at indexi
tox
. - You may repeat this procedure as many times as needed.
Return True if it is possible to construct the target
array from A
otherwise return False.
Example 1:
Input: target = [9,3,5]
Output: true
Explanation: Start with [1, 1, 1]
[1, 1, 1], sum = 3 choose index 1
[1, 3, 1], sum = 5 choose index 2
[1, 3, 5], sum = 9 choose index 0
[9, 3, 5] Done
Example 2:
Input: target = [1,1,1,2]
Output: false
Explanation: Impossible to create target array from [1,1,1,1].
Example 3:
Input: target = [8,5]
Output: true
Constraints:
N == target.length
1 <= target.length <= 5 * 10^4
1 <= target[i] <= 10^9
题意
给定一个全为1的数组,每次可以进行如下操作:计算数组之和为x;任选数组中一个元素将它替换为x。问能否经过若干次操作后,使得初始全为1的数组变为目标数组。
思路
倒推,数组中最大的数一定是通过上述流程得到的。每次选择最大的数top,将其减去剩余数之和remain得到top执行一次流程前的值,重复操作直到所有数被还原为1。注意注意特殊情况的处理。
代码实现
Java
class Solution {
public boolean isPossible(int[] target) {
if (target.length == 1 && target[0] != 1) return false;
long sum = 0; // 和可能越界
Queue<Integer> pq = new PriorityQueue<>(Comparator.reverseOrder());
for (int num : target) {
sum += num;
pq.offer(num);
}
while (pq.peek() > 1) {
int top = pq.poll();
sum -= top;
if (sum == 1) return true; // 如果剩余之和为1,那么一定能将top还原为1,如:[4,1]
if (top <= sum || top % sum == 0) return false; // 特殊情况:[2,2]
top %= sum; // 还原top
sum += top;
pq.offer((int) top);
}
return true;
}
}