日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LeetCode 1354. 多次求和构造目标数组(优先队列+逆向思考)

發布時間:2024/7/5 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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的那個數進隊列


超時例子

class Solution { public:bool isPossible(vector<int>& target) {int i, num;long sum = 0, s;priority_queue<int> q;//默認大頂堆for(i = 0; i < target.size(); ++i){sum += target[i];//總和q.push(target[i]);}while(q.top() != 1){s = sum-q.top();//剩余的和num = q.top()-s;//棧頂-s,應該為1或者比1大的數if(num < 1)//小于1則falsereturn false;q.pop();//彈出棧頂q.push(num);//把剩余的數再push進去sum -= s;//和減少了s}return true;} };

超時原因: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. 多次求和构造目标数组(优先队列+逆向思考)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。