LeetCode 面試經典 150_數組/字符串_分發糖果(15_135_C++_困難)(貪心算法)

LeetCode 面試經典 150_數組/字符串_分發糖果(15_135_C++_困難)

    • 題目描述:
    • 輸入輸出樣例:
    • 題解:
      • 解題思路:
        • 思路一(貪心算法):
      • 代碼實現
        • 代碼實現(思路一(貪心算法)):
        • 代碼實現(對思路一代碼進行優化):
        • 以思路一為例進行調試

題目描述:

n 個孩子站成一排。給你一個整數數組 ratings 表示每個孩子的評分。
你需要按照以下要求,給這些孩子分發糖果:

  • 每個孩子至少分配到 1 個糖果。
  • 相鄰兩個孩子中,評分更高的那個會獲得更多的糖果。

請你給每個孩子分發糖果,計算并返回需要準備的 最少糖果數目

輸入輸出樣例:

示例 1:
輸入:ratings = [1,0,2]
輸出:5
解釋:你可以分別給第一個、第二個、第三個孩子分發 2、1、2 顆糖果。

示例 2:
輸入:ratings = [1,2,2]
輸出:4
解釋:你可以分別給第一個、第二個、第三個孩子分發 1、2、1 顆糖果。
第三個孩子只得到 1 顆糖果,這滿足題面中的兩個條件。

提示:
n == ratings.length
1 <= n <= 2 * 109
0 <= ratings[i] <= 2 * 109

題解:

解題思路:

思路一(貪心算法):

1、左右代表相鄰的兩個元素(只考慮兩個相鄰元素)
->->->->->->->
左 > 右 ;右=1
左 < 右 ;右=左+1
左 = 右 ;右=1
<-<-<-<-<-<-<-
左 > 右 ;左=右+1
左 < 右 ;左=1
左 = 右 ;左=1
① 從 左->右 掃描時,先將每個孩子的糖果置為 1,如果相鄰元素中右側的元素比左側大,則右側元素的糖果數等于左側糖果數+1。
② 從 右->左 掃描時,先將每個孩子的糖果置為 1,如果相鄰元素中左側的元素比右側大,則左側元素的糖果數等于右側糖果數+1。
③ 再挑選出 左->右 和 右->左中較大的元素。

:ratings = [1,0,2],left 代表從左到右,right 代表從右到左。
left = [1,1,2]
right= [2,1,1]
ans = 2+1+2=5

2、復雜度分析:
① 時間復雜度:O(n),n 代表數組的長度,遍歷三遍數組。
② 空間復雜度:O(n),n 代表數組的長度,使用 left 存儲從左向右的糖果,使用 right 存儲從右向左的糖果。

代碼實現

代碼實現(思路一(貪心算法)):
class Solution1 {
public:// 主函數,返回給定評分數組所需的糖果總數int candy(vector<int>& ratings) {int count = ratings.size(); // 獲取評分數組的長度vector<int> left(count, 1); // 初始化一個長度為count的數組left,表示每個孩子至少有1顆糖// 從左到右遍歷評分數組,計算每個孩子的糖果數(如果比前一個孩子的評分高,糖果數加1)for (int i = 1; i < count; i++) {if (ratings[i] > ratings[i - 1]) { // 如果當前孩子的評分高于前一個孩子left[i] = left[i - 1] + 1; // 當前孩子的糖果數比前一個孩子多1}}vector<int> right(count, 1); // 初始化一個長度為count的數組right,表示每個孩子至少有1顆糖// 從右到左遍歷評分數組,計算每個孩子的糖果數(如果比下一個孩子的評分高,糖果數加1)for (int i = count - 2; i >= 0; i--) {if (ratings[i] > ratings[i + 1]) { // 如果當前孩子的評分高于下一個孩子right[i] = right[i + 1] + 1; // 當前孩子的糖果數比下一個孩子多1}}int ans = 0; // 用于存儲總糖果數// 遍歷所有孩子,取每個孩子在left和right數組中的最大值(這保證了當前孩子能夠得到最大可能的糖果數)for (int i = 0; i < count; i++) {ans += max(left[i], right[i]); // 取最大值,避免重復計算}return ans; // 返回總糖果數}
};
代碼實現(對思路一代碼進行優化):
/** 優化存儲空間(只使用一個額外的數組)* 只使用一個額外的數組存儲 左->右 掃描的結果* 從 右->左 掃描時,邊計算 右->左 的糖果數量,邊計算ans(總糖果數)* 時間復雜度:O(n),遍歷了兩遍數組。* 空間復雜度:O(n),使用了一個額外的數組空間。*/
class Solution2 {
public:// 主函數,返回給定評分數組所需的糖果總數int candy(vector<int>& ratings) {int count = ratings.size(); // 獲取評分數組的長度vector<int> left(count, 1); // 初始化一個長度為count的數組left,表示每個孩子至少有1顆糖// 從左到右遍歷評分數組,計算每個孩子的糖果數(如果比前一個孩子的評分高,糖果數加1)for (int i = 1; i < count; i++) {if (ratings[i] > ratings[i - 1]) { // 如果當前孩子的評分高于前一個孩子left[i] = left[i - 1] + 1; // 當前孩子的糖果數比前一個孩子多1}}// 初始化右邊的糖果數,先假設最后一個孩子右邊沒有其他孩子int ans = left[count-1];  // 初始總糖果數為最后一個孩子的糖果數int right = 1;  // 右側的臨時糖果數,初始化為1,因為每個孩子至少有1顆糖// 從右到左遍歷評分數組,計算每個孩子的糖果數(如果比下一個孩子的評分高,糖果數加1)for (int i = count - 2; i >= 0; i--) {if (ratings[i] > ratings[i + 1]) { // 如果當前孩子的評分高于下一個孩子right = right + 1; // 當前孩子的糖果數增加} else {right = 1; // 如果當前孩子的評分不高于下一個孩子,糖果數恢復為1}// 更新總糖果數:取左邊和右邊糖果數的最大值// left[i]是從左到右計算的糖果數,right是從右到左計算的糖果數ans += max(right, left[i]); // 累加當前孩子的最大糖果數}return ans; // 返回總糖果數}
};
以思路一為例進行調試
#include<iostream>
#include<vector>
using namespace std;class Solution1 {
public:// 主函數,返回給定評分數組所需的糖果總數int candy(vector<int>& ratings) {int count = ratings.size(); // 獲取評分數組的長度vector<int> left(count, 1); // 初始化一個長度為count的數組left,表示每個孩子至少有1顆糖// 從左到右遍歷評分數組,計算每個孩子的糖果數(如果比前一個孩子的評分高,糖果數加1)for (int i = 1; i < count; i++) {if (ratings[i] > ratings[i - 1]) { // 如果當前孩子的評分高于前一個孩子left[i] = left[i - 1] + 1; // 當前孩子的糖果數比前一個孩子多1}}// 初始化右邊的糖果數,先假設最后一個孩子右邊沒有其他孩子int ans = left[count-1];  // 初始總糖果數為最后一個孩子的糖果數int right = 1;  // 右側的臨時糖果數,初始化為1,因為每個孩子至少有1顆糖// 從右到左遍歷評分數組,計算每個孩子的糖果數(如果比下一個孩子的評分高,糖果數加1)for (int i = count - 2; i >= 0; i--) {if (ratings[i] > ratings[i + 1]) { // 如果當前孩子的評分高于下一個孩子right = right + 1; // 當前孩子的糖果數增加} else {right = 1; // 如果當前孩子的評分不高于下一個孩子,糖果數恢復為1}// 更新總糖果數:取左邊和右邊糖果數的最大值// left[i]是從左到右計算的糖果數,right是從右到左計算的糖果數ans += max(right, left[i]); // 累加當前孩子的最大糖果數}return ans; // 返回總糖果數}
};int main(int argc, char const *argv[])
{vector<int> ratings = {1,0,2};Solution1 s;cout<<s.candy(ratings);return 0;
}

LeetCode 面試經典 150_數組/字符串_分發糖果(15_135)原題鏈接
歡迎大家和我溝通交流(????)

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

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

相關文章

配置timer控制 IO的輸出(STC8)

使用STC8的Timer控制IO輸出 STC8系列單片機具有多個定時器&#xff0c;可以用于精確控制IO口的輸出狀態。以下是使用Timer0和Timer1控制IO輸出的方法。 初始化Timer0 配置Timer0為16位自動重裝模式&#xff0c;用于周期性控制IO輸出&#xff1a; /************************ 定時…

【Python練習】086. 編寫一個函數,實現簡單的DHCP服務器功能

086. 編寫一個函數,實現簡單的DHCP服務器功能 086. 編寫一個函數,實現簡單的DHCP服務器功能 安裝依賴庫 示例代碼 代碼說明 示例輸出 注意事項 擴展功能 DHCP服務器功能實現方法 依賴庫安裝 基本功能實現 功能說明 運行方法 注意事項 擴展功能 086. 編寫一個函數,實現簡單的…

生產環境Tomcat運行一段時間后,如何測試其性能是否滿足后續使用

要測試生產環境中已運行一段時間的Tomcat性能是否滿足后續使用需求&#xff0c;需從基礎監控、負載壓力測試、配置合理性校驗、穩定性驗證等多維度入手&#xff0c;結合工具和實際業務場景定位瓶頸&#xff0c;確保其能應對未來可能的流量增長。以下是具體方法和步驟&#xff1…

Qt中的設計模式:經典的MVC,MVP和MVVM

Qt中的設計模式&#xff1a;經典的MVC&#xff0c;MVP和MVVM 前言 ? 筆者這里最近正在研究經典的三大 Model/View 框架&#xff0c;不得不說&#xff0c;我先前的確寫過Qt在這里的體現&#xff0c;但是&#xff0c;筆者認為之前的文章中&#xff0c;我只是機械的memcpy的Qt的…

Windows浮動ip怎么配置

Windows浮動IP怎么配置&#xff0c;達到IP漂移的效果&#xff0c;方法肯定是有的&#xff0c;這里我推薦一款好用的高可用Vip漂移軟件PanguVip&#xff0c;我們先看下最終達到的效果圖&#xff0c;如下所示PanguVip軟件免費下載百度網盤為您提供文件的網絡備份、同步和分享服務…

[langchain] Sync streaming vs Async Streaming

我不太清楚langchain中的sync stream 和 async steam有什么關系和區別sync stream from langchain.chat_models import init_chat_model from langchain_deepseek.chat_models import ChatDeepSeek import dotenv dotenv.load_dotenv()messages [ ("system", &quo…

nginx下lua的實現機制、Lua錯誤處理、面向對象

nginx下lua的實現機制 nginxlua概述 nginx&#xff1a;功能由模塊提供。 http模塊、events模塊&#xff0c;mail模塊。 處理http請求的時候&#xff0c;可以利用模塊做一些功能&#xff1a;eg&#xff1a;登錄校驗&#xff0c;js合并&#xff0c;數據庫訪問&#xff0c;鑒權。 …

Axure基于中繼器實現的組件庫(導航菜單、動態表格)

摘要 本文將為您詳細介紹基于 Axure 的中繼器組件庫中的 9 個獨特組件&#xff0c;這些組件不僅能夠極大地提升您的原型設計效率&#xff0c;還能為您的項目增添令人驚嘆的交互效果和視覺呈現。 引言 在當今快速發展的數字產品設計領域&#xff0c;原型設計工具的革新不斷推動著…

Kafka 生產者與消費者分區策略全解析:從原理到實踐

一、生產者分區策略1.1 分區好處&#xff08;1&#xff09;便于合理使用存儲資源&#xff0c;每個Partition在一個Broker上存儲&#xff0c;可以把海量的數據按照分區切割成一塊一塊數據存儲在多臺Broker上。合理控制分區的任務&#xff0c;可以實現負載均衡的效果。&#xff0…

高頻面試點:深入理解 TCP 三次握手與四次揮手

在網絡通信的世界里,TCP(Transmission Control Protocol,傳輸控制協議)是確保數據可靠傳輸的基石。其中,三次握手建立連接、四次揮手斷開連接的過程,更是 Java 秋招面試中的高頻考點。今天,我們就深入剖析這兩個關鍵過程,結合原理、代碼示例與面試真題,幫你吃透知識點…

k8s-nfs實現創建sc的兩種方式

法一&#xff1a;基于 官方 NFS CSI 插件 法二&#xff1a;基于 nfs-subdir-external-provisioner 法一 官方 NFS CSI 插件 大致步驟# 安裝 NFS sudo apt update sudo apt install -y nfs-kernel-server # 創建共享目錄 sudo mkdir -p /data/nfs sudo chmod 777 /data/nfs # 配…

n8n 入門指南:更適合跨境出海搞錢的AI智能體

如果你最近刷到 AI 圈的分享應該會發現——n8n 又火起來了。其實 n8n 早在 2020 年左右就被程序員玩過一波&#xff0c;當時很多人拿它做網站自動發郵件、消息轉發之類的“流程自動化”。但那時候 AI 還沒這么卷&#xff0c;大家也沒覺得多有用。n8n為什么最近又翻紅&#xff1…

【數據分享】各省農業土地流轉率(2010-2023)

數據介紹土地流轉是推動農業規模化、現代化發展的關鍵機制。為助力相關研究&#xff0c;現分享一份覆蓋全國30個省級行政區、時間跨度為2010-2023年的農業土地流轉率面板數據集。本數據直接提取自權威統計年報&#xff0c;具有較高的參考價值。一、數據概覽覆蓋范圍&#xff1a…

音視頻時間戳獲取與同步原理詳解

引言&#xff1a;為什么音視頻同步如此重要&#xff1f; 在音視頻技術領域&#xff0c;"同步"是決定用戶體驗的核心要素。想象一下觀看電影時畫面與聲音錯位0.5秒的場景&#xff1a;角色說話時嘴唇動作與聲音不匹配&#xff0c;爆炸場景的視覺沖擊先于音效到達——這…

Day38--動態規劃--322. 零錢兌換,279. 完全平方數,139. 單詞拆分,56. 攜帶礦石資源(卡碼網),背包問題總結

Day38–動態規劃–322. 零錢兌換&#xff0c;279. 完全平方數&#xff0c;139. 單詞拆分&#xff0c;56. 攜帶礦石資源&#xff08;卡碼網&#xff09;&#xff0c;背包問題總結 今天的是幾道經典的“完全背包”題目。前兩道題目&#xff0c;要區分求的是“價值”&#xff0c;還…

應用層Http協議(1)

應用層Http協議&#xff08;1&#xff09; 在互聯網世界中&#xff0c;HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本傳輸協議&#xff09;是一個至關重要的協議。它定義了客戶端&#xff08;如瀏覽器&#xff09;與服務器之間如何通信&#xff0c;以交換或傳…

elementui input無法輸入問題

背景。開發小程序。自定義表單在pc段設置好input輸入框屬性后。 在小程序端無法輸入原因&#xff1a;長度受限制&#xff0c;導致input組件的maxlength屬性認為長度是0導致無法輸入任何值。看解釋是應為遇到空字符串等情況會設置為0解決。因為未找到設置maxlength為0處&#xf…

算法_python_學習記錄_02

算法學習和視頻學習過程中&#xff0c;有許多前幾天還不知道的知識點&#xff0c;現在一點一點歸納整理出來&#xff0c;穩步前進&#xff0c;前進~ 20_貪心算法系列題 00_參考文檔 詳解貪心算法&#xff08;Python實現貪心算法典型例題&#xff09;_順序貪婪算法-CSDN博客P…

Meta AI水印計劃的致命缺陷——IEEE Spectrum深度文獻精讀

一、原文信息 標題: Metas AI Watermarking Plan Is Flimsy, at Best 中文譯名: Meta的AI水印計劃脆弱不堪 作者: David Evan Harris(加州大學伯克利分校)、Lawrence Norden(紐約大學法學院) 發表日期: 2024年3月5日 發表期刊: IEEE Spectrum 二、原文全文翻譯 Met…

gpt-oss 全量技術解讀

一、概述 gpt-oss 是 OpenAI 發布的開放權重&#xff08;open-weight&#xff09;模型系列&#xff0c;面向強推理、Agent 能力與多樣化應用場景。 提供兩種規格&#xff1a; gpt-oss-120b&#xff1a;面向生產與高推理需求&#xff0c;單卡 80GB GPU&#xff08;如 NVIDIA …