【leetcode】【hard】1354. Construct Target Array With Multiple Sums

1354. Construct Target Array With Multiple Sums

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:

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

题目链接:https://leetcode-cn.com/problems/construct-target-array-with-multiple-sums/

思路

试着做几个样例,可找到几个规律:

1)计算过程可逆,可从结果倒推回全1的数组;

2)最大值一定要大于其他值之和;

3)由2)可以推出,不能同时存在两个相同的最大值;

4)由3)可以推出,给出的数组中,所有非1的值都必须唯一,因为他们在逆计算时都有机会成为最大值。

因此,由1)可以定下程序的总体思路是逆推,直到数组变回全1,或者中途违反了其他规律而失败。

但这里有个坑:计算超时。样例: [1, 1000000000]。

因此这个过程肯定还有可压缩的地方,是我们没有找到的规律。参考这个未通过样例,可以看出另一个规律:

5)当某个值连续几次都最大时,其他值没有改变,只有它本身不断减去其他值,连续减的结果 = 取余。

6)结合2)和5)可推出,如果最大值取余为0了,而第二大的数却不是1,说明最大值没有满足2),可以提前判定失败。

ok差不多了,上代码。

class Solution {
public:
    bool isPossible(vector<int>& target) {
        if(target.size()==0) return true;
        if(target.size()==1 ){
            if(target[0]==1) return true;
            else return false;
        }
        priority_queue<int> record;
        long sum = 0;
        for(int i=0; i<target.size(); ++i){
            record.push(target[i]);
            sum += target[i];
        }
        while(sum>target.size()){
            int iter = record.top();
            record.pop();
            if(iter == 1) return true;
            if(iter > sum - iter){
                if(record.top() == 1) return true;
                int tmp = sum - iter;
                int sub = iter / tmp;
                int num = iter % tmp;
                if(num == 0) return false;
                record.push(num);
                sum -= tmp * sub;
            }else return false;
        }
        return true;
    }
};
发布了126 篇原创文章 · 获赞 2 · 访问量 3734

猜你喜欢

转载自blog.csdn.net/lemonade13/article/details/104467858