Java入门算法(贪心篇)丨蓄力计划
本專欄已參加蓄力計(jì)劃,感謝讀者支持
往期文章
一. Java入門算法(貪心篇)丨蓄力計(jì)劃
二. Java入門算法(暴力篇)丨蓄力計(jì)劃
三. Java入門算法(排序篇)丨蓄力計(jì)劃
四. Java入門算法(遞歸篇)丨蓄力計(jì)劃
五. Java入門算法(雙指針篇)丨蓄力計(jì)劃
六. Java入門算法(數(shù)據(jù)結(jié)構(gòu)篇)丨蓄力計(jì)劃
七. Java入門算法(滑動(dòng)窗口篇)丨蓄力計(jì)劃
你好,我是Ayingzz,Ayi是我的名字,ing進(jìn)行時(shí)代表我很有動(dòng)力,zz提醒我按時(shí)睡覺(jué) ~
- 篇幅短小精悍,適合初學(xué)者反復(fù)咀嚼:此專欄的文章并不是一系列大而全的整理文章,而是一系列簡(jiǎn)明扼要的算法入門講解文章,篇幅短而內(nèi)容精,有利于初學(xué)者針對(duì)一種或多種算法快速入門。
- 例題簡(jiǎn)單易懂,讓你印象深刻:引入精選LeetCode簡(jiǎn)易算法例題,通過(guò)生動(dòng)形象的講解對(duì)其思路進(jìn)行簡(jiǎn)明剖析,更容易上手并掌握。
- 涉及算法種類廣:雙指針、遞歸、排序、貪心、分治、動(dòng)態(tài)規(guī)劃、滑動(dòng)窗口、DFS...各類基礎(chǔ)算法收攬其中。
為什么要學(xué)算法?
對(duì)于所有的Problems-Solving的過(guò)程都可以理解為算法,程序員對(duì)算法或多或少都有著一些復(fù)雜的情感,為什么一定要學(xué)算法?
- "程序 = 數(shù)據(jù)結(jié)構(gòu) + 算法"。這個(gè)公式相信已經(jīng)耳濡目染,目前在各大廠的面試?yán)?#xff0c;對(duì)基礎(chǔ)算法的考察的比重逐年增加,只寫會(huì)某種語(yǔ)言的工程代碼顯然并不太夠,大部分面試官會(huì)優(yōu)先考慮掌握算法的面試者。在現(xiàn)實(shí)開(kāi)發(fā)里,僅使用一些簡(jiǎn)單的算法就可以快讀優(yōu)化各種繁雜的工程代碼,降低時(shí)間復(fù)雜度與工程運(yùn)行速度,提升用戶體驗(yàn)。
- 對(duì)算法的熱愛(ài)。作為程序員或多或少對(duì)算法都有著某種情感上的執(zhí)著與偏愛(ài),如果你還是學(xué)生,想?yún)⑴c各類的競(jìng)賽,那么入門算法即是數(shù)學(xué)建模、軟件開(kāi)發(fā)、算法等各類競(jìng)賽的敲門磚,選手的動(dòng)力就是對(duì)算法的追求與熱愛(ài),類似的有ACM、藍(lán)橋杯等。
專欄思路和內(nèi)容大綱
基礎(chǔ)部分:
進(jìn)階部分:
適宜人群
- 對(duì)算法感興趣的初學(xué)者
- 想加強(qiáng)算法基本功的讀者
貪心篇
- 往期文章
- 為什么要學(xué)算法?
- 專欄思路和內(nèi)容大綱
- 適宜人群
- ~
- 前言
- (本篇內(nèi)容)
- 花朵 Flower
- 糖果 Candy
- 餅干 Cookie
- 股票 Stock
- (推薦練習(xí))
- 加油站
- 跳躍游戲
~
前言
貪心算法是入門算法之一,它在百度百科上是這樣解釋的。
貪心算法的使用條件有兩個(gè):
一個(gè)問(wèn)題的整體最優(yōu)解可以通過(guò)一系列局部最優(yōu)解的選擇達(dá)到,并且每次的選擇可以依賴以前作出的選擇,但不依賴于后面要作出的選擇,這就是貪心選擇性質(zhì)。
當(dāng)一個(gè)問(wèn)題的最優(yōu)解包含其子問(wèn)題的最優(yōu)解時(shí),稱此問(wèn)題具有最優(yōu)子結(jié)構(gòu)性質(zhì)。問(wèn)題的最優(yōu)子結(jié)構(gòu)性質(zhì)是該問(wèn)題可用貪心法求解的關(guān)鍵所在。在實(shí)際應(yīng)用中,至于什么問(wèn)題具有什么樣的貪心選擇性質(zhì)是不確定的,需要具體問(wèn)題具體分析。
(本篇內(nèi)容)
花朵 Flower
LeetCode題目描述:605.種花問(wèn)題(Easy)示例
輸入:flowerbed = [1,0,0,0,1], n = 1 輸出:true ------------------------------------ 輸入:flowerbed = [1,0,0,0,1], n = 2 輸出:false思路:
貪心策略的使用:
class Solution {public boolean canPlaceFlowers(int[] flowerbed, int n) {int L = flowerbed.length;for (int i = 0; i < L; i += 2) {if (flowerbed[i] == 0) {if (i == L - 1 || flowerbed[i + 1] == 0) {n--;}else{i++;}}}return n <= 0;} }糖果 Candy
LeetCode題目描述:135. 分發(fā)糖果(Hard)
老師想給孩子們分發(fā)糖果,有 N 個(gè)孩子站成了一條直線,老師會(huì)根據(jù)每個(gè)孩子的表現(xiàn),預(yù)先給他們?cè)u(píng)分。
你需要按照以下要求,幫助老師給這些孩子分發(fā)糖果:示例
輸入:[1,0,2] 輸出:5 解釋:你可以分別給這三個(gè)孩子分發(fā) 2、1、2 顆糖果。 ----------------------------------------------------- 輸入:[1,2,2] 輸出:4 解釋:你可以分別給這三個(gè)孩子分發(fā) 1、2、1 顆糖果。第三個(gè)孩子只得到 1 顆糖果,這已滿足上述兩個(gè)條件。思路:
貪心策略的使用:
class Solution {public static int candy(int[] ratings) {int[] candy = new int[ratings.length];// 每個(gè)孩子至少有一個(gè)糖果,初始化數(shù)組元素為1Arrays.fill(candy, 1);// 從左往右,每次考慮左邊孩子評(píng)分比右邊孩子評(píng)分高的情況for (int i = 0; i < ratings.length - 1; ++i) {if (ratings[i + 1] > ratings[i]) {candy[i + 1] = candy[i] + 1;}}// 從右往左,每次考慮右邊孩子評(píng)分比左邊孩子評(píng)分高的情況for (int i = ratings.length - 1; i > 0; --i) {if (ratings[i - 1] > ratings[i] && candy[i - 1] <= candy[i]) {candy[i - 1] = candy[i] + 1;} }// 答案數(shù)組求和int min_candy_sum = 0;for (int x : candy) { min_candy_sum += x;}return min_candy_sum;} }餅干 Cookie
LeetCode題目描述:455. 分發(fā)餅干(Easy)示例
輸入: g = [1,2,3], s = [1,1] 輸出: 1 解釋: 你有三個(gè)孩子和兩塊小餅干,3個(gè)孩子的胃口值分別是:1,2,3。 雖然你有兩塊小餅干,由于他們的尺寸都是1,你只能讓胃口值是1的孩子滿足。 所以你應(yīng)該輸出1。 --------------------------------------------------------------------- 輸入: g = [1,2], s = [1,2,3] 輸出: 2 解釋: 你有兩個(gè)孩子和三塊小餅干,2個(gè)孩子的胃口值分別是1,2。 你擁有的餅干數(shù)量和尺寸都足以讓所有孩子滿足。 所以你應(yīng)該輸出2.思路:
股票 Stock
LeetCode題目描述:122. 買賣股票的最佳時(shí)機(jī) ll(Easy)*注:你必須在再次購(gòu)買前出售掉之前的股票。
示例
輸入: [7,1,5,3,6,4] 輸出: 7解釋: 在第 2 天(股票價(jià)格 = 1)的時(shí)候買入,在第 3 天(股票價(jià)格 = 5)的時(shí)候賣出, 這筆交易所能獲得利潤(rùn) = 5 -1 = 4 。隨后,在第 4 天(股票價(jià)格 = 3)的時(shí)候買入,在第 5 天(股票價(jià)格 = 6)的時(shí)候賣出, 這筆交易所能獲得利潤(rùn) = 6 -3 = 3 。
輸入: [1,2,3,4,5] 輸出: 4解釋: 在第 1 天(股票價(jià)格 = 1)的時(shí)候買入,在第 5 天 (股票價(jià)格 = 5)的時(shí)候賣出, 這筆交易所能獲得利潤(rùn) = 5-1 = 4 。
思路:
貪心策略的使用:
class Solution {public int maxProfit(int[] prices) {int ans = 0;int n = prices.length;if (n == 1) {return 0;}for (int i = 0; i < n - 1; ++i) {// 尋找極小值while (i < n - 1 && prices[i] > prices[i + 1]) {++i;}// 買入ans -= prices[i];// 尋找極大值while (i < n - 1 && prices[i] < prices[i + 1]) {++i;}// 賣出ans += prices[i];}return ans;} }(推薦練習(xí))
\
加油站
- 在一條環(huán)路上有 N 個(gè)加油站,其中第 i 個(gè)加油站有汽油 gas[i] 升。
- 你有一輛油箱容量無(wú)限的的汽車,從第 i 個(gè)加油站開(kāi)往第 i+1 個(gè)加油站需要消耗汽油 cost[i] 升。你從其中的一個(gè)加油站出發(fā),開(kāi)始時(shí)油箱為空。
- 如果你可以繞環(huán)路行駛一周,則返回出發(fā)時(shí)加油站的編號(hào),否則返回 -1。
跳躍游戲
- 給定一個(gè)非負(fù)整數(shù)數(shù)組 nums ,你最初位于數(shù)組的 第一個(gè)下標(biāo) 。
- 數(shù)組中的每個(gè)元素代表你在該位置可以跳躍的最大長(zhǎng)度。
- 判斷你是否能夠到達(dá)最后一個(gè)下標(biāo)。
/
總的來(lái)說(shuō),具體問(wèn)題具體分析,只要確定一個(gè)問(wèn)題的局部最優(yōu)解可以導(dǎo)致問(wèn)題的整體最優(yōu)解,那么即可以考慮選擇貪心策略、分治或動(dòng)態(tài)規(guī)劃(下篇)解決。
若有不當(dāng)歡迎指正。本專欄持續(xù)周更,預(yù)計(jì)7月結(jié)束
總結(jié)
以上是生活随笔為你收集整理的Java入门算法(贪心篇)丨蓄力计划的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 方舟武器品质怎么提升(方舟生存进化)
- 下一篇: Java入门算法(暴力篇)丨蓄力计划