一、Problem
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.
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
二、Solution
方法一:暴力排序(超時)
- 逆向思維,從 target 變爲全 1 數組怎麼做?
- 我們知道將 [1, 3, 1] 變爲 [1, 1, 1] 需要將 a 排序,然後由 a[2] -= a[0] + a[1] 得出公式: -=
class Solution {
long sum(int[] a, int r) {
long sum = 0;
for (int i = 0; i < r; i++) sum += a[i];
return sum;
}
public boolean isPossible(int[] tar) {
int n = tar.length-1;
Arrays.sort(tar);
while (tar[n] > 1) {
if (tar[0] < 0) return false;
tar[n] -= sum(tar, n);
Arrays.sort(tar);
}
return tar[0] == 1;
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,
方法二:暴力優化(超時)
由上可得,上一輪的被賦值的元素 = 這一輪的最大值 ,故,我們只需記錄每一輪的最大值 ,以及其下標 ,即可省去冗餘的排序。同時我們需要明確幾個結束條件即可判斷是否能由 target 變爲全 1 數組:
- 因爲數組至少存在兩個元素,所以當某一輪改變後,發現 sum < 2,return false
- 因爲能被構造出來的最小元素一定不小於 1,所以當某一輪的元素
2 × maxn - sum
比 1 小了,return false - 如果最後
maxn = 1 && sum = n
,說明構造成功…
class Solution {
public boolean isPossible(int[] tar) {
int n = tar.length;
while (true) {
int maxi = 0;
long maxn = 0, sum = 0;
for (int i = 0; i < n; i++) {
sum += tar[i];
if (tar[i] > maxn) {
maxi = i;
maxn = tar[i];
}
}
if (sum < 2) break;
if (maxn == 1 && sum == n) return true;
if (2*maxn - sum < 1) return false;
tar[maxi] = (int) (2*maxn - sum);
}
return false;
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,