Day31|貪心算法1

貪心的本質是選擇每一階段的局部最優,從而達到全局最優。

無固定套路,舉不出反例,就可以試試貪心。

一般解題步驟:

1.將問題分解成若干子問題

2.找出適合的貪心策略

3.求解每一個子問題的最優解

4.將局部最優解堆疊成全局最優解

分發餅干

思路:為了滿足更多的小孩,就不要造成餅干尺寸的浪費,大尺寸的餅干既可以滿足胃口大的孩子,也可以滿足胃口小的孩子,充分利用餅干尺寸喂飽一個,全局最優就是喂飽盡可能多的小孩。可以嘗試使用貪心策略,先將餅干數組和小孩數組進行排序。然后從后向前遍歷小孩數組,用大餅干優先滿足胃口大的,并統計滿足小孩數量。

class Solution{
public:int findContentChildren(vector<int>&g,vector<int>& s){sort(g.begin(),g.end());sort(s.begin(),s.end());int index = s.size() - 1;int result = 0;for(int i = g.size() - 1;i >= 0; i--){if(index >= 0 && s[index] >= g[i]){result++;index--;}}return result;}
};

從代碼中可以看出,index用來控制餅干數組的遍歷,遍歷餅干沒有再起一個循環,而是采用自減的方式,這是常用的技巧。

不可以先遍歷比骨干再遍歷胃口,因為外面for,i是固定移動的,if的index才是符合條件移動的。

?反過來,先滿足胃口小的,從小到大去滿足:

class Solution{
public:int findContentChildren(vector<int>& g,vector<int>&s){sort(g.begin(),g.end());sort(s.begin(),s.end());int index = 0;for(int i = 0; i < size(); i++){if(index < g.size() && g[index] <= s[i]){index++;}}return index;}
};
//思路一
class Solution{public int findContentChildren(int[] g, int[] s){Arrays.sort(g);Arrays.sort(s);int start = 0;int count = 0;for(int i = 0; i < s.length && start < g.length; i++){if(s[i] >= g[start]){start++;count++;}}return count;}
}
class Solution{public int findContentChildren(int[] g,int[] s){Arrays.sort(g);//排序胃口Arrays.sort(s);//排序餅干int count = 0;int start = s.length - 1;//胃口數組長度,從start開始遍歷,倒著遍歷,先考慮胃口大的//遍歷胃口,從大到小for(int index = g.length - 1;index >= 0;index--){if(start >= 0 && g[index] <= s[start]){start--;//從大到小count++;//滿足一個計數+1}}return count;//返回計數}
}

擺動序列

如果連續數字之間的差嚴格地在正數和負數之間交替,則數字序列稱為擺動序列。第一個差(如果存在地話),可能是正數或負數,少于兩個元素的序列也是擺動序列。

給定一個整數序列,返回作為擺動序列的最長子序列的長度。通過從原始序列中刪除一些元素來獲得子序列,剩下的元素保持其原始順序。

思路:

貪心

刪除單調坡度上的節點(不包括單調坡度兩端的節點),那么這個坡度就可以有兩個局部峰值。

整體最優:整個序列有最多的局部峰值,從而達到最長擺動序列。

實際操作中,刪除操作都不用,因為題目要求的是最長擺動子序列的長度,所以只需要統計數組的峰值數量就可以了(相當于是刪除單一坡度上的節點,然后統計長度)

這就是貪心所貪的地方,?讓峰值盡可能地保持峰值,然后刪除單一坡度上的節點。

在計算是否有峰值的時候,大家知道遍歷的下標i,計算presiff(nums[i] - nums[i - 1])和curdiff(nums[i + 1] - nums[i]),如果presiff < 0 && surdiff > 0或者prediff > 0 && curdiff < 0,此時就有波動就需要統計。

這是我們思考本題的一個大體思路,但本題還要考慮三種情況:

1.上下坡有平坡

[1,2,2,2,2,1]刪除左邊的三個2,或者刪除右邊的三個2,擺動長度為3

當i指向第一個2的時候,prediff > 0&&curdiff=0,當 i 指向最后一個2的時候,prediff=0 && curdiff <0.

如果采用刪除左面三個2的規則,那么當prediff = 0&&curdiff < 0也要記錄一個峰值,因為他是把之前相同的元素都刪掉留下的峰值。

我們記錄峰值的條件應該是:(preDiff <=0 &&curDiff > 0)||(preDiff >= 0&&curDiff < 0)?

2.數組首尾兩端

本題統計峰值的時候,數組最左面和最右面如何統計。

當有兩個不同的元素時,擺動序列也是2.

例如[2,5],如果靠統計差值來計算峰值個數,就需要考慮數組最左面和最右面的特殊情況。

因為我們在計算prediff(nums[i] - nums[i - 1])和curdiff(nums[i+1] - nums[i])的時候,至少需要三個數字才能計算,而數組只有兩個數字。這里如果只有兩個數字,且是不同的元素,那結果為2.

3.單調坡中有平坡

之前我們在討論 情況一 :相同數字練習的時候,prediff = 0,curdiff < 0或者>0也記為波谷

為了統一規則。針對序列[2,5],可以假設為[2,2,5],這樣就有了坡度,即preDiff = 0.

[2,2,5]

針對以上情形,result初始值為1,此時curDiff > 0&&preDiff<=0,那么result++(計算了左面的峰值),最后得到結果為2(峰值個數為2即擺動序列長度為2)

class Solution{
public:int wiggleMaxLength(vector<int>&nums){if(num.size() <= 1)return nums.size();int curDiff = 0;int preDiff = 0;int result = 1;for(int i = 0; i < nums.size() - 1;i++){curDiff = nums[i + 1]-nums[i];if((preDiff <= 0 &&curDiff >0)||(preDiff >= 0 && curDiff < 0)){result++;}preDiff = curDiff;}};
}

3.在上面解法中,忽略了第三種情況,即如果在一個單調坡度上有平坡,例如[1,2,2,2,3,4]

圖中我們可以看出,應該記錄2,單調中的平坡不能算作峰值(擺動)

?需要在坡度擺動變化時,更新prediff,這樣prediff在單調區間有平坡的時候就不會發生變化,造成誤判。

class Solution{
public:int wiggleMaxLength(vctor<int>&nums){if(nums.size() <= 1)return nums.size();int curDiff = 0;int preDiff = 0;int result = 1;for(int i = 0; i < nums.size() - 1;i++){curDiff = nums[i + 1] - nums[i];//出現峰值if((preDiff <= 0 && curDiff > 0)||(preDiff >= 0&& curDiff < 0)){result++;preDiff = curDiff;}}return result;}
};

用動態規劃求解

思路:

對于我們當前考慮的這個數,要么是作為山峰(nums[i] > nums[i - 1]),要么是作為山谷(即nums[i] < nums[i-1])

設dp狀態dp[i][0],表示考慮前i個數,第i個數作為山峰的擺動子序列的最長長度。

設dp狀態為dp[i][1],表示考慮前i個數,第i個數作為山谷的擺動子序列的最長長度

則轉移方程為:

dp[i][0] = max(dp[i][0],dp[j][1]? + 1),其中0<j<i且nums[j] < nums[i],表示將

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/718615.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/718615.shtml
英文地址,請注明出處:http://en.pswp.cn/news/718615.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【MySQL】深入解析 Buffer Pool 緩沖池

文章目錄 1、前置知識1.1、Buffer Pool介紹1.2、后臺線程1.2.1、Master Thread1.2.2、IO Thread1.2.3、Purge Thread1.2.4、Page Cleaner Thread 1.3、重做日志緩沖池 2、Buffer Pool 組成2.1、數據頁2.2、索引頁2.3、undo頁2.4、插入緩沖2.5、鎖空間2.6、數據字典2.6、自適應哈…

JavaScript之structuredClone現代深拷貝

在JavaScript中&#xff0c;實現深拷貝的方式有很多種&#xff0c;每種方式都有其優點和缺點。今天介紹一種原生JavaScript提供的structuredClone實現深拷貝。 下面列舉一些常見的方式&#xff0c;以及它們的代碼示例和優缺點&#xff1a; 1. 使用JSON.parse(JSON.stringify(…

代碼隨想錄 二叉樹第四周

目錄 617.合并二叉樹 700.二叉搜索樹中的搜索 98.驗證二叉搜索樹 530.二叉搜索樹的最小絕對差 501.二叉搜索樹中的眾樹 236.二叉樹的最近公共祖先 617.合并二叉樹 617. 合并二叉樹 簡單 給你兩棵二叉樹&#xff1a; root1 和 root2 。 想象一下&#xff0c;當你將其…

【Rust】——切片

&#x1f383;個人專欄&#xff1a; &#x1f42c; 算法設計與分析&#xff1a;算法設計與分析_IT閆的博客-CSDN博客 &#x1f433;Java基礎&#xff1a;Java基礎_IT閆的博客-CSDN博客 &#x1f40b;c語言&#xff1a;c語言_IT閆的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

第105講:Mycat垂直分表實戰:從規劃到解決問題的完整指南

文章目錄 1.垂直分表的背景2.垂直分表案例實戰2.1.垂直分表規劃2.2.配置Mycat實現垂直分表2.3.重啟Mycat2.4.在Mycat命令行中導入數據結構2.5.查看由Mycat分表后每個分片上存儲的表2.6.Mycat垂直分表后可能遇到的問題2.7.垂直分表完成 1.垂直分表的背景 我們的商城系統數據庫&…

Unity編輯器下如何獲取物體(GameObject)的中心位置

注意僅能在編輯器下才能使用該方法 實現方式依靠UnityEditor.Tools提供的參數&#xff0c;具體實現如下&#xff1a; 獲取單個物體的中心坐標 public static Vector3 GetGameObjectCenter(GameObject gameObject) {// 選中物體Selection.activeObject gameObject;// 記錄當前…

C#中Byte.Parse的用法,如果需要解析含有數字以外的字符,應該如何使用?

在C#中&#xff0c;Byte.Parse用于將字符串解析為byte類型的數字。它的用法如下&#xff1a; byte result Byte.Parse(str);其中&#xff0c;str是要解析的字符串。 如果要解析的字符串含有數字以外的字符&#xff0c;Byte.Parse會拋出一個FormatException異常。為了處理這種…

javaWebssh水利綜合信息管理系統myeclipse開發mysql數據庫MVC模式java編程計算機網頁設計

一、源碼特點 java ssh水利綜合信息管理系統是一套完善的web設計系統&#xff08;系統采用ssh框架進行設計開發&#xff09;&#xff0c;對理解JSP java編程開發語言有幫助&#xff0c;系統具有完整的源代碼和數據庫&#xff0c;系統主要采用B/S模式開發。開發環境為TOMCA…

MATLAB 實現貝葉斯決策

1. 原理 后驗概率&#xff1a; 1.最小錯誤率決策&#xff08;最大后驗概率決策&#xff09;&#xff1a; 2.最小風險決策&#xff1a; 3.正態分布下的貝葉斯決策 2. 過程 2.1 訓練集數據可視化 導入兩類訓練集數據&#xff0c;并繪制其數據分布&#xff0c;如下&#xff1a;…

云時代【5】—— LXC 與 容器

云時代【5】—— LXC 與 容器 三、LXC&#xff08;一&#xff09;基本介紹&#xff08;二&#xff09;相關 Linux 指令實戰&#xff1a;使用 LXC 操作容器 四、Docker&#xff08;一&#xff09;刪除、安裝、配置&#xff08;二&#xff09;鏡像倉庫1. 分類2. 相關指令&#xf…

JavaSE-09(Java IO精華總結)

Java IO 簡單做個總結&#xff1a; 1 .InputStream/OutputStream 字節流的抽象類。2 .Reader/Writer 字符流的抽象類。3 .FileInputStream/FileOutputStream 節點流&#xff1a;以字節為單位直接操作“文件”。4 .ByteArrayInputStream/ByteArrayOutputStream 節點流&#xff…

Running job: job_1709516801756_0003

** yarn運行卡在Running job: job_1709516801756_0003問題解決&#xff1a; ** 在運行wordcount時出現錯誤&#xff0c;一直卡住 運行命令&#xff1a;hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount /input /output 出現錯誤&#xff1a…

嶺回歸算法

回歸分析方法是利用數理統計方法分析數據&#xff0c;建立自變量和因變量間的回歸模型&#xff0c;用于預測因變量變化的分析方法。其中比較經典的是HoerI和Kennard提出的嶺回歸算法。嶺回歸算法是在最小二乘法的基礎上引|入正則項&#xff0c;使回歸模型具有較好泛化能力和穩定…

經典思路!人參葉際微生物如何發8分文章?

中國中醫科學院中藥研究所在《Environmental Microbiome》期刊上(IF7.9)發表了關于葉際真菌微生態網絡的文章&#xff0c;該研究通過對ITS測序結果和環境因子測定結果以及皂苷含量測定結果進行生信分析&#xff0c;提出了維持微生態網絡的穩定性策略和影響皂苷含量的因素。 期刊…

H12-821_113

113.如圖所示是路由器現ATE輸出的部分信息&#xff0c;以下關于這部分信息的描述&#xff0c;錯誤的是哪一項&#xff1f; A.display pim rp-info命令用來查看組播組對應的RP信息 B.RP地址是2.2.2.2 C.組地址是225.0.0.0 D.RP的優先級是0 答案&#xff1a;C 注釋&#xff1a; …

HCIA-Datacom題庫(自己整理分類的)_29_PPP協議判斷【6道題】

1.數據鏈路層采用PPP封裝鏈路兩端的IP地址可以不在同一個網段。√ 2.PPP鏈路兩端不在同一網段不能通信。 3.參考以下拓撲及配置&#xff0c;路由器R1與R2通過Serial低速線纜連接&#xff0c;且數據鏈路層封裝使用PPP。當R1和R2的Holdtime不一致時&#xff0c;PPP協商失敗&…

python使用常用的路徑問題

PythonPath多個路徑的使用 通過命令行直接修改 export PYTHONPATH$PYTHONPATH:/path/to/directoryPythonPath多個路徑的使用 export PYTHONPATH$PYTHONPATH:/path/to/directory1:/path/to/directory2PythonPath多個路徑的使用 python path 移除路徑 python path python中…

爬蟲實戰——麻省理工學院新聞

文章目錄 發現寶藏一、 目標二、 淺析三、獲取所有模塊四、請求處理模塊、版面、文章1. 分析切換頁面的參數傳遞2. 獲取共有多少頁標簽并遍歷版面3.解析版面并保存版面信息4. 解析文章列表和文章5. 清洗文章6. 保存文章圖片 五、完整代碼六、效果展示 發現寶藏 前些天發現了一…

jQuery AJAX get() 和 post() 方法—— W3school 詳解 簡單易懂(二十四)

jQuery get() 和 post() 方法用于通過 HTTP GET 或 POST 請求從服務器請求數據。 HTTP 請求&#xff1a;GET vs. POST 兩種在客戶端和服務器端進行請求-響應的常用方法是&#xff1a;GET 和 POST。 GET - 從指定的資源請求數據POST - 向指定的資源提交要處理的數據 GET 基本…

MySQL面試題-日志(答案版)

日志 1、為什么需要 undo log&#xff1f; &#xff08;1&#xff09;實現事務回滾&#xff0c;保障事務的原子性。 事務處理過程中&#xff0c;如果出現了錯誤或者用戶執 行了 ROLLBACK 語句&#xff0c;MySQL 可以利用 undo log 中的歷史數據將數據恢復到事務開始之前的狀態…