C++算法 —— 貪心(4)

文章目錄

  • 1、分發餅干
  • 2、最優除法
  • 3、跳躍游戲Ⅱ
  • 4、跳躍游戲Ⅰ
  • 5、加油站
  • 6、單調遞增的數字
  • 7、壞了的計算器


1、分發餅干

455. 分發餅干

在這里插入圖片描述
其實看完這個題會發現,如果給定的兩個數組不排序的話會非常難受,所以無論怎樣,先排序。接下來需要比較兩個數組的值,可以用雙指針來指向。兩個數組的兩個元素比較時,和之前有相同的思路,如果滿足條件,那么后面的元素都比這個元素大,肯定也滿足,但為了滿足更多次的條件,所以就選用最小的那個值;如果不滿足條件,這里就跳過去,找下一個更大的元素去看看能否滿足條件。這也就是貪心思想。

    int findContentChildren(vector<int>& g, vector<int>& s) {sort(g.begin(), g.end());sort(s.begin(), s.end());int res = 0, m = g.size(), n = s.size();for(int i = 0, j = 0; i < m && j < n; ++i, ++j){while(j < n && s[j] < g[i]) ++j;if(j < n) res++;}return res;}

2、最優除法

553. 最優除法

在這里插入圖片描述
無論怎樣,假設abcdefg7個數,a / b / c / d / e / f,整個式子就是一個分式,a一定在分子,b一定在分母。對于貪心來說,讓分子變大,讓分母變小,就是最優解。這道題來看,其實應當讓分子變大就是它的最優解,所以接下來就要讓分子變大。讓分子變大的辦法就是在把b ~ f都放到一個括號里,這樣就變成了 a * c * d * e * f / b。

    string optimalDivision(vector<int>& nums) {int n = nums.size();if(n == 1) return to_string(nums[0]);if(n == 2) return to_string(nums[0]) + "/" + to_string(nums[1]);string res = to_string(nums[0]) + "/(" + to_string(nums[1]);for(int i = 2; i < n; ++i){res += "/" + to_string(nums[i]);}res += ")";return res;}

3、跳躍游戲Ⅱ

45. 跳躍游戲 II

在這里插入圖片描述
這道題意思就是如果是[2, 3, 1, 5, 4],那么在0下標位置時最多可以跳2步到1這個位置。

這道題可以用動規,以i位置為結尾,遍歷一遍前面所有的元素,如果能從某個位置跳過來,那就選那個位置,而那個位置存儲了到它的最小跳躍數,然后+1即可,但這樣是n ^ 2的時間復雜度,思路并不行。

這道題的思路可以是一個類似層序遍歷的過程。假設一個數組[2, 3, 1, 1, 4, 2, 6, 7, 1, 5, 8],從0下標開始,是2,我們能夠確定跳到3或1這個點,也就是第一次選定起點后確定了下一次起跳的左端點和右端點;接著,3可以跳到1,1,4,而1這里,就加上貪心,因為3跳得遠,且它一定比1要至少1,所以1能跳到的,3一定能跳到的,所以這里就只考慮大的數字,跳的區間為114,但是重疊了,重疊部分是2下標處的1,所以把這部分去掉,只看1和4,1就是左端點,4就是右端點;接著從4走,能到2671,這時候14和2671沒有重疊的,所有不會劃掉一部分,2就是左端點,1就是右端點。這樣的過程就是選定了一個點后,就能確定下一次的左端點和右端點,所以很像層序遍歷。

這個思路的時間復雜度是O(N)。

    int jump(vector<int>& nums) {int left = 0, right = 0, maxPos = 0, n = nums.size(), res = 0;while(left <= right)//防止跳不到n - 1位置{if(maxPos >= n - 1)//先判斷是否已經能跳到最后一個位置return res;for(int i = left; i <= right; ++i){maxPos = max(maxPos, nums[i] + i);}left = right + 1;right = maxPos;res++;}return -1;}

4、跳躍游戲Ⅰ

55. 跳躍游戲

在這里插入圖片描述
先看跳躍游戲Ⅱ。

其實就是改兩處

    bool canJump(vector<int>& nums) {int left = 0, right = 0, maxPos = 0, n = nums.size();while(left <= right)//防止跳不到n - 1位置{if(maxPos >= n - 1)//先判斷是否已經能跳到最后一個位置return true;for(int i = left; i <= right; ++i){maxPos = max(maxPos, nums[i] + i);}left = right + 1;right = maxPos;}return false;}

5、加油站

134. 加油站

在這里插入圖片描述
在這里插入圖片描述
按照這個題的思路來看,兩個數組要同時看,這時不如作為一個數組,因為真正需要的是差。gas和cost兩個數組每每對應,用gas的減cost的,比如例1,就得到[-2, -2, -2, 3, 3]。最簡單的辦法就是暴力解法,依次枚舉所有起點,模擬加油的流程。

實際上,這道題可以在暴力解法上改進而得到。差值的數組不需要創建出來,不過下面還是看差值數組。用i表示下標,然后用一個step變量,表示走多少步,比如走0步就還是原地,走1步就到下一個位置,不過要%上數組大小,這樣就不會越界了。

    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {int n = gas.size();for(int i = 0; i < n; i++){int rest = 0;for(int step = 0; step < n; step++){int index = (i + step) % n;rest = rest + gas[index] - cost[index];if(rest < 0) break;}if(rest >= 0) return i;}return -1;}

不過這樣肯定超出時間限制。現在基于這個來優化。假設差值數組是abcdefg,從a走到f就不能走了,說明a + b + c + d + e + f < 0,暴力解法就會從b再來一遍,但這樣明顯做了無用功。上面的式子小于0,那么去掉a,還是小于0,所以就不用管這些了,直接從g位置再出發。這樣平均時間復雜度就是O(N)了。

    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {int n = gas.size();for(int i = 0; i < n; i++){int rest = 0;int step = 0;for(; step < n; step++){int index = (i + step) % n;rest = rest + gas[index] - cost[index];if(rest < 0) break;}if(rest >= 0) return i;i = i + step;}return -1;}

6、單調遞增的數字

738. 單調遞增的數字

在這里插入圖片描述
當然最簡單的方法就是暴力枚舉,從這個數字到0,判斷每一個數字是否是單調遞增,找到的第一個就是結果。不過重點在于如何判斷單調遞增。

對于一個數字,如果想對每一位做一些判斷,轉換成字符串就好。另一個經典操作就是模10再除10,就能從個位開始拿到每一位。

這個暴力解法的時間復雜度是O(nlogn),取一個數字的每一位的時間復雜度是logn。

但這里不用暴力解法,要用貪心,不過這更像找規律。

從頭開始判斷,如果發現了不是遞增,那要對字符串如何操作?比如123454367,到了5這個位置就不能繼續了,但因為要找更小的數字,那么4367不能改為6367。我們可以修改5,把它減1,然后后面的數字全變成9,就是要求的數字。但這里還有問題,如果是連續的幾個5之后有個4呢?這樣就得把第一個5改成4,后面全變成9。

    int monotoneIncreasingDigits(int n) {string s = to_string(n);int i = 0, m = s.size();while(i + 1 < m && s[i] <= s[i + 1]) ++i;if(i + 1 == m) return n;while(i - 1 >= 0 && s[i] == s[i - 1]) --i;s[i]--;for(int j = i + 1; j < m; ++j) s[j] = '9';return stoi(s);}

7、壞了的計算器

991. 壞了的計算器

在這里插入圖片描述
對于小于目標的數,那么乘2會更快地接近目標,但是也有不是最優解的,比如6和目標10。

這道題適合逆著思考,把操作變成除2和+1。
這個題沒有小數,所以能除2的只能是偶數,那么遇到奇數的話就只能+1。偶數可以除2,可以+1。把目標值變成原始值,原始值則變成目標值。假設原有的目標值是end,原始值是begin。

針對偶數,如果end <= begin,也就是目標值更小,那么遇到偶數就得+1。如果end > begin,奇數還是只能+1,而偶數,經過證明,其實是先除更優。

    int brokenCalc(int startValue, int target) {//正難則反 + 貪心int res = 0;while(target > startValue){if(target % 2 == 0) target /= 2;else target += 1;res++;}return res + startValue - target;//目標值變成小于原始值了,奇偶數都是+1,所以就是加上差值。}

結束。

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

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

相關文章

項目管理套路:看這一篇絕對夠用??

寫論文必不可少的&#xff0c;就是創建代碼并進行實驗。好的項目管理可以讓實驗進行得更加順利。本篇博客以一次項目實踐為例&#xff0c;介紹項目管理的方法&#xff0c;以及可能遇到的問題&#xff0c;并提供一些可行的解決方案。 目錄 項目管理工具開始第一步版本管理十分關…

GB/T 32223-2015 建筑門窗五金件檢測

建筑門窗五金件包括操縱部件&#xff08;傳動機構用執手、旋轉執手、雙面執手、單點鎖閉器&#xff09;、承載部件&#xff08;合頁&#xff0c;鉸鏈、滑撐、滑輪&#xff09;、傳動啟閉部件&#xff08;傳動鎖閉器、多點鎖閉器、插銷&#xff09;、輔助部件&#xff08;撐擋、…

【JavaWeb】TomcatJavaWebHTTP

Tomcat&JavaWeb&HTTP 文章目錄 Tomcat&JavaWeb&HTTP一、Tomcat1.1 版本選擇及安裝1.2 目錄1.3 WEB項目部署的方式 二、IDEA中Java Web開發部署流程三、HTTP協議3.1 發展歷程3.2 HTTP協議的會話方式3.3 請求報文3.4 響應報文 一、Tomcat Tomcat是Apache 軟件基…

php xml數據轉數組兩種方式

目錄 方法一、可以使用simplexml_load_string()函數將XML數據轉換為數組。 方法二、使用PHP內置的DOMDocument類來將XML數據轉換為數組的方法 方法一、可以使用simplexml_load_string()函數將XML數據轉換為數組。 $xmlData <root><name>John Doe</name>&l…

NX二次開發UF_CSYS_create_matrix 函數介紹

文章作者&#xff1a;里海 來源網站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CSYS_create_matrix Defined in: uf_csys.h int UF_CSYS_create_matrix(const double matrix_values [ 9 ] , tag_t * matrix_id ) overview 概述 Creates a 3 x 3 matrix. 創建…

nodejs+vue+python+PHP+微信小程序-青云商場管理系統的設計與實現-安卓-計算機畢業設計

研究步驟、措施&#xff1a; &#xff08;1&#xff09;與指導老師確定系統主要功能&#xff1b; &#xff08;2&#xff09;做需求分析及功能模塊劃分&#xff1b; &#xff08;3&#xff09;指導老師通過后&#xff0c;設計出用例圖&#xff0c;E-R圖&#xff0c;功能模塊圖 …

【XSLVGL2.0】如何新增一種語言和詞條

XSLVGL2.0 開發手冊 【XSLVGL2.0】如何新增一種語言和詞條 1、概述2、以外置資源的方式增加詞條3、以內置資源的方式增加詞條4、使用方法1、概述 本文件旨在介紹新增一種語言詞條的方法 2、以外置資源的方式增加詞條 假設項目需要增加一種英文的詞條。一般地,我們采用國際…

Git-將指定文件回退到指定版本

場景1&#xff1a;修改了文件/path/to/file&#xff0c;沒有提交&#xff0c;但是覺得改的不好&#xff0c;想還原。 解決&#xff1a; git checkout -- /path/to/file 場景2&#xff1a;修改了文件/path/to/file&#xff0c;已經提交&#xff0c;但是覺得改的不好&#xff0c…

老牌開源 SVG 編輯器 SVGEdit 是如何架構的?

大家好&#xff0c;我是前端西瓜哥。這次簡單看看 SVGEdit 的架構。 SVGEdit 的版本為 7.2.0。 SVGEdit 一款非常老牌的 SVG 圖形編輯器&#xff0c;用于編輯處理 SVG&#xff0c;start 數目前是 5.8k。 它的優點在于經過多年的開發&#xff0c;完成度高&#xff0c;較為成熟&a…

大眾博客系統測試報告【改】

一、項目背景 大眾博客系統采用前后端分離的方法來實現&#xff0c;同時使用了數據庫來存儲相關的數據&#xff0c;同時將其部署到云服務器上。前端主要有四個頁面構成&#xff1a;登錄頁、列表頁、詳情頁以及編輯頁&#xff0c;以上模擬實現了最簡單的大眾博客系統。其結合后端…

Tars-GO 開發

默認環境是安裝好的 創建服務: tarsgo make App Server Servant GoModuleName Tars 實例的名稱&#xff0c;有三個層級&#xff0c;分別是 App&#xff08;應用&#xff09;、Server&#xff08;服務&#xff09;、Servant&#xff08;服務者&#xff0c;有時也稱 Object&am…

LeetCode Hot100 74.搜索二維矩陣

題目&#xff1a; 給你一個滿足下述兩條屬性的 m x n 整數矩陣&#xff1a; 每行中的整數從左到右按非嚴格遞增順序排列。每行的第一個整數大于前一行的最后一個整數。 給你一個整數 target &#xff0c;如果 target 在矩陣中&#xff0c;返回 true &#xff1b;否則&#x…

數據結構——堆的實現

堆的實現-----C語言版 目錄&#xff1a;一、堆的實現1.1堆的定義1.2堆的實現1.2.1堆的各個接口1.2.2堆的向上調整1.2.3堆的向下調整1.2.4堆的定義聲明和初始化1.2.5堆的數據處理1.2.6堆的判空和堆的數據個數以及堆銷毀1.2.7堆的代碼實現 二、TOP—K問題 目錄&#xff1a; 一、…

C++ 文件和流、異常處理、動態內存、預處理器

一、C文件和流&#xff1a; 在C中進行文件處理&#xff0c;需要包含頭文件<iostream>和<fstream>。fstream標準庫定義的三個新的數據類型&#xff1a; 數據類型 描述 ofstream 該數據類型表示輸出文件流&#xff0c;用于創建文件并向文件寫入信息。 ifstream …

vscode項目推送到git

1、打開項目文件 打開文件后點擊vs code左側工具欄中第三個源代碼管理圖標&#xff0c;點擊初始化倉庫&#xff0c;此時會創建一個本地倉庫會檢查該項目中的文件變更 2、創建遠程倉庫 點擊克隆/下載&#xff0c;復制HTTPS地址 3、添加遠程地址 1&#xff09;圖形化操作 2…

Leetcode刷題之用隊列實現棧(C語言版)

Leetcode刷題之用隊列實現棧&#xff08;C語言版&#xff09; 一、題目描述二、題目要求三、題目示例四、題目解析Ⅰ、MyStack* myStackCreateⅡ、void myStackPush(MyStack* obj, int x)Ⅲ、int myStackPop(MyStack* obj)Ⅳ、int myStackTop(MyStack* obj)Ⅴ、bool myStackEmp…

文件夾重命名:徹底擺脫數字困擾,批量修改文件夾名去除數字

在日常生活和工作中&#xff0c;經常會遇到需要修改文件夾名稱的情況。有時候是因為文件夾名稱中包含了數字&#xff0c;有時候是因為文件夾名稱不符合規范。無論出于什么原因&#xff0c;修改文件夾名稱都是一件非常繁瑣的事情。尤其是需要修改大量文件夾名稱時&#xff0c;手…

Jenkins 整合 Docker 自動化部署

Docker 安裝 Jenkins 配置自動化部署 1. Docker 安裝 Jenkins 1.1 拉取鏡像文件 docker pull jenkins/jenkins1.2 創建掛載文件目錄 mkdir -p $HOME/jenkins_home1.3 啟動容器 docker run -d -p 8080:8080 -v $HOME/jenkins_home:/var/jenkins_home --name jenkins jenkin…

CentOS rpm安裝Nginx和配置

CentOS rpm安裝Nginx和配置 官方下載地址: http://nginx.org/en/download.html 介紹 Nginx(“engine x”)是一款由俄羅斯的程序設計師Igor Sysoev所開發高性能的 Web和 反向代理 服務器&#xff0c;也是一個 IMAP/POP3/SMTP 代理服務器。 rpm包安裝 #安裝nginx&#xff0c…

k8s部署的java服務查看連接nacos緩存的配置文件

一、問題描述 k8s部署的java服務&#xff0c;使用nacos中的配置文件&#xff0c;需要在緩存中查看該服務具體是使用到了哪些配置文件 二、解決 參考文檔: https://nacos.io/zh-cn/docs/system-configurations.html 文檔描述如下: 進入java服務容器進入用戶目錄下的nacos&a…