题目

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 that 0 <= i < target.size and set the value of A 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 A otherwise return False.

Example 1:

  1. Input: target = [9,3,5]
  2. Output: true
  3. Explanation: Start with [1, 1, 1]
  4. [1, 1, 1], sum = 3 choose index 1
  5. [1, 3, 1], sum = 5 choose index 2
  6. [1, 3, 5], sum = 9 choose index 0
  7. [9, 3, 5] Done

Example 2:

  1. Input: target = [1,1,1,2]
  2. Output: false
  3. Explanation: Impossible to create target array from [1,1,1,1].

Example 3:

  1. Input: target = [8,5]
  2. 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

  1. class Solution {
  2. public boolean isPossible(int[] target) {
  3. if (target.length == 1 && target[0] != 1) return false;
  4. long sum = 0; // 和可能越界
  5. Queue<Integer> pq = new PriorityQueue<>(Comparator.reverseOrder());
  6. for (int num : target) {
  7. sum += num;
  8. pq.offer(num);
  9. }
  10. while (pq.peek() > 1) {
  11. int top = pq.poll();
  12. sum -= top;
  13. if (sum == 1) return true; // 如果剩余之和为1,那么一定能将top还原为1,如:[4,1]
  14. if (top <= sum || top % sum == 0) return false; // 特殊情况:[2,2]
  15. top %= sum; // 还原top
  16. sum += top;
  17. pq.offer((int) top);
  18. }
  19. return true;
  20. }
  21. }