LeetCode 1354. 多次求和构造目标数组(优先队列+逆向思考)
生活随笔
收集整理的這篇文章主要介紹了
LeetCode 1354. 多次求和构造目标数组(优先队列+逆向思考)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1. 題目
給你一個整數數組 target 。一開始,你有一個數組 A ,它的所有元素均為 1 ,你可以執行以下操作:
- 令 x 為你數組里所有元素的和
- 選擇滿足 0 <= i < target.size 的任意下標 i ,并讓 A 數組里下標為 i 處的值為 x 。
- 你可以重復該過程任意次
如果能從 A 開始構造出目標數組 target ,請你返回 True ,否則返回 False 。
示例 1: 輸入:target = [9,3,5] 輸出:true 解釋:從 [1, 1, 1] 開始 [1, 1, 1], 和為 3 ,選擇下標 1 [1, 3, 1], 和為 5, 選擇下標 2 [1, 3, 5], 和為 9, 選擇下標 0 [9, 3, 5] 完成示例 2: 輸入:target = [1,1,1,2] 輸出:false 解釋:不可能從 [1,1,1,1] 出發構造目標數組。示例 3: 輸入:target = [8,5] 輸出:true提示: N == target.length 1 <= target.length <= 5 * 10^4 1 <= target[i] <= 10^9來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/construct-target-array-with-multiple-sums
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
2. 解題
- 和會越加越大,要先往最小的上面加(動態的過程)
- 逆向思考,給定的數組,數字全部push進優先隊列
- 數組和往下減去最大的,應該等于1,若小于1,false
- 大于1,先pop原數,再push大于1的那個數進隊列
超時例子
超時原因:queue的數據類型int溢出了,改為long
class Solution { public:bool isPossible(vector<int>& target) {long sum = 0, s, i, num;priority_queue<long> q;//默認大頂堆for(i = 0; i < target.size(); ++i){sum += target[i];//總和q.push(target[i]);}while(!q.empty() && q.top() != 1){s = sum-q.top();//剩余的和num = q.top()-s;//棧頂-s,應該為1或者比1大的數if(num < 1)//小于1則falsereturn false;q.pop();//彈出棧頂if(num != 1)//等于1就不用再放進去了,節省時間q.push(num);sum -= s;//和減少了s}return true;} };
leetcode該題的數據有點弱,上面解法在例子 [1000000000, 1]時超時。
比如對于 [5, 9, 31] 而言,31 - 14 = 17 還是最大數,不如干脆 31 - 14 * 2 = 9
更改如下,增加倍數scale
class Solution { public:bool isPossible(vector<int>& target) {if(target.size() == 1)return target[0] == 1;long sum = 0, s, i, num, tp, scale;priority_queue<long> q;//默認大頂堆for(i = 0; i < target.size(); ++i){sum += target[i];//總和q.push(target[i]);}while(q.top() != 1){tp = q.top();q.pop();s = sum-tp;//剩余的和scale = max(1,int((tp-q.top())/s));//至少1倍num = tp-scale*s;//棧頂-n*s,應該為1或者比1大的數if(num < 1)//小于1則falsereturn false;q.push(num);sum -= scale*s;//和減少了n*s}return true;} };總結
以上是生活随笔為你收集整理的LeetCode 1354. 多次求和构造目标数组(优先队列+逆向思考)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2019年学习总结
- 下一篇: LeetCode 116. 填充每个节点