LeetCode 1354. 多次求和构造目标数组

博客讨论了LeetCode 1354题目的解题思路,作者最初尝试错误的方法是将一个数字持续累加,直到达到目标值。后来发现正确解决方案是通过逆向操作,识别每次操作后最大数字的变化,并通过优化避免超时。关键在于确定最大数字可以被拆分为多少次其他数字的和,即计算k为`(max_num - 1) / other_sum`,避免新数字变为0的情况。
摘要由CSDN通过智能技术生成

https://leetcode-cn.com/problems/construct-target-array-with-multiple-sums/

这道题一开始想了个办法,但是错了,错在假设其他数字都是不变的,一直向一个数字加,直到凑到其中一个目标最小数字。。。

看了题解才知道,这道题是可以逆操作的。因为是其他所有数字加到一个数字上,所以最大的数字肯定是刚操作的数字。只要反操作一下。

值得注意的是需要优化,不然会超时,一个最大的数字,假设是a+other_sum,如果a还是最大的数字(通过a大于other_sum来判断,如果大于other_sum,肯定大于其他数字),那么a还是可以再拆,a=b+other_sum,所以综合起来,max_num= c + k*other_sum,,其中c>=1,是一个整数,所以我们可以直接减去k*other_sum,相当于逆操作的多次。至于怎么求k,我们注意到c是一个正数,c>=1 && c < other_sum,所以k*other_sum这部分最大是 max_num-1,然后用(max_num-1)/other_sum,这里减一是因为如果max_num整除other_sum,那新的数字就是0了。

 

class Solution {
public:
    bool isPossible(vector<int>& target) {
        priority_queue<int> q;
        long long sum=0;
        for(int i=0;i<target.size();i++){
            q.push(target[i]);
            sum+=target[i];
        }

        while(q.top()!=1){
            int max_num=q.top();
            q.pop();
            long long other_sum=sum-max_num;
            if(other_sum==0)
                return false;
            if(max_num-other_sum<1){
                return false;
            }
        
            int add_time=(max_num-1)/other_sum;
            if(max_num-add_time*other_sum<1)
                return false;
            q.push(max_num-add_time*other_sum);
            sum-=other_sum*add_time;
        
            
        }
        return true;

        
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值