在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

代碼中是數學圖像解法和貪心解法

新材料在線 ? 來源:labuladong ? 作者:labuladong ? 2021-09-01 14:14 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

今天講一個貪心的老司機的故事,就是力扣第 134 題「加油站」:

5fda8eb2-fbbe-11eb-9bcf-12bb97331649.jpg

題目應該不難理解,就是每到達一個站點i,可以加gas[i]升油,但離開站點i需要消耗cost[i]升油,問你從哪個站點出發,可以兜一圈回來。

要說暴力解法,肯定很容易想到,用一個 for 循環遍歷所有站點,假設為起點,然后再套一層 for 循環,判斷一下是否能夠轉一圈回到起點:

int n = gas.length;

for (int start = 0; start 《 n; start++) {

for (int step = 0; step 《 n; step++) {

int i = (start + step) % n;

tank += gas[i];

tank -= cost[i];

// 判斷油箱中的油是否耗盡

}

}

很明顯時間復雜度是 O(N^2),這么簡單粗暴的解法一定不是最優的,我們試圖分析一下是否有優化的余地。

暴力解法是否有重復計算的部分?是否可以抽象出「狀態」,是否對同一個「狀態」重復計算了多次?

我們前文 動態規劃詳解 說過,變化的量就是「狀態」。那么觀察這個暴力窮舉的過程,變化的量有兩個,分別是「起點」和「當前油箱的油量」,但這兩個狀態的組合肯定有不下 O(N^2) 種,顯然沒有任何優化的空間。

所以說這道題肯定不是通過簡單的剪枝來優化暴力解法的效率,而是需要我們發現一些隱藏較深的規律,從而減少一些冗余的計算。

下面我們介紹兩種方法巧解這道題,分別是數學圖像解法和貪心解法。

圖像解法

汽車進入站點i可以加gas[i]的油,離開站點會損耗cost[i]的油,那么可以把站點和與其相連的路看做一個整體,將gas[i] - cost[i]作為經過站點i的油量變化值:

這樣,題目描述的場景就被抽象成了一個環形數組,數組中的第i個元素就是gas[i] - cost[i]。

有了這個環形數組,我們需要判斷這個環形數組中是否能夠找到一個起點start,使得從這個起點開始的累加和一直大于等于 0。

如何判斷是否存在這樣一個起點start?又如何計算這個起點start的值呢?

我們不妨就把 0 作為起點,計算累加和的代碼非常簡單:

int n = gas.length, sum = 0;

for (int i = 0; i 《 n; i++) {

// 計算累加和

sum += gas[i] - cost[i];

}

sum就相當于是油箱中油量的變化,上述代碼中sum的變化過程可能是這樣的:

顯然,上圖將 0 作為起點肯定是不行的,因為sum在變化的過程中小于 0 了,不符合我們「累加和一直大于等于 0」的要求。

那如果 0 不能作為起點,誰可以作為起點呢?

看圖說話,圖像的最低點最有可能可以作為起點:

如果把這個「最低點」作為起點,就是說將這個點作為坐標軸原點,就相當于把圖像「最大限度」向上平移了。

再加上這個數組是環形數組,最低點左側的圖像可以接到圖像的最右側:

這樣,整個圖像都保持在 x 軸以上,所以這個最低點 4,就是題目要求我們找的起點。

不過,經過平移后圖像一定全部在 x 軸以上嗎?不一定,因為還有無解的情況:

如果sum(gas[。..]) 《 sum(cost[。..]),總油量小于總的消耗,那肯定是沒辦法環游所有站點的。

綜上,我們就可以寫出代碼:

int canCompleteCircuit(int[] gas, int[] cost) {

int n = gas.length;

// 相當于圖像中的坐標點和最低點

int sum = 0, minSum = Integer.MAX_VALUE;

int start = 0;

for (int i = 0; i 《 n; i++) {

sum += gas[i] - cost[i];

if (sum 《 minSum) {

// 經過第 i 個站點后,使 sum 到達新低

// 所以站點 i + 1 就是最低點(起點)

start = i + 1;

minSum = sum;

}

}

if (sum 《 0) {

// 總油量小于總的消耗,無解

return -1;

}

// 環形數組特性

return start == n ? 0 : start;

}

以上是觀察函數圖像得出的解法,時間復雜度為 O(N),比暴力解法的效率高很多。

下面我們介紹一種使用貪心思路寫出的解法,和上面這個解法比較相似,不過分析過程不盡相同。

貪心解法

用貪心思路解決這道題的關鍵在于以下這個結論:

如果選擇站點i作為起點「恰好」無法走到站點j,那么i和j中間的任意站點k都不可能作為起點。

比如說,如果從站點1出發,走到站點5時油箱中的油量「恰好」減到了負數,那么說明站點1「恰好」無法到達站點5;那么你從站點2,3,4任意一個站點出發都無法到達5,因為到達站點5時油箱的油量也必然被減到負數。

如何證明這個結論?

假設tank記錄當前油箱中的油量,如果從站點i出發(tank = 0),走到j時恰好出現tank 《 0的情況,那說明走到i, j之間的任意站點k時都滿足tank 》 0,對吧。

如果把k作為起點的話,相當于在站點k時tank = 0,那走到j時必然有tank 《 0,也就是說k肯定不能是起點。

拜托,從i出發走到k好歹tank 》 0,都無法達到j,現在你還讓tank = 0了,那更不可能走到j了對吧。

綜上,這個結論就被證明了。

回想一下我們開頭說的暴力解法是怎么做的?

如果我發現從i出發無法走到j,那么顯然i不可能是起點。

現在,我們發現了一個新規律,可以推導出什么?

如果我發現從i出發無法走到j,那么i以及i, j之間的所有站點都不可能作為起點。

看到冗余計算了嗎?看到優化的點了嗎?

這就是貪心思路的本質,如果找不到重復計算,那就通過問題中一些隱藏較深的規律,來減少冗余計算。

根據這個結論,就可以寫出如下代碼:

int canCompleteCircuit(int[] gas, int[] cost) {

int n = gas.length;

int sum = 0;

for (int i = 0; i 《 n; i++) {

sum += gas[i] - cost[i];

}

if (sum 《 0) {

// 總油量小于總的消耗,無解

return -1;

}

// 記錄油箱中的油量

int tank = 0;

// 記錄起點

int start = 0;

for (int i = 0; i 《 n; i++) {

tank += gas[i] - cost[i];

if (tank 《 0) {

// 無法從 start 走到 i

// 所以站點 i + 1 應該是起點

tank = 0;

start = i + 1;

}

}

return start == n ? 0 : start;

}

這個解法的時間復雜度也是 O(N),和之前圖像法的解題思路有所不同,但代碼非常類似。

其實,你可以把這個解法的思路結合圖像來思考,可以發現它們本質上是一樣的,只是理解方式不同而已。

對于這種貪心算法,沒有特別套路化的思維框架,主要還是靠多做題多思考,將題目的場景進行抽象的聯想,找出隱藏其中的規律,從而減少計算量,進行效率優化。

好了,這道題就講到這里,希望對你拓寬思路有幫助。

責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 數據
    +關注

    關注

    8

    文章

    7253

    瀏覽量

    91749
  • 代碼
    +關注

    關注

    30

    文章

    4898

    瀏覽量

    70585

原文標題:當老司機學會了貪心算法

文章出處:【微信號:xincailiaozaixian,微信公眾號:新材料在線】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    模擬電路故障診斷

    本書主要介紹了故障字典法,元件參數解法,故障的預猜驗證法,逼近法,模擬電路故障診斷的現狀及發展趨勢。
    發表于 03-07 14:38

    Altium技術賦能Woodoo開發新一代建筑材料

    解法國生物材料公司Woodoo如何使用Altium技術將木材可持續地轉化為獨特的新一代建筑材料。
    的頭像 發表于 02-28 16:17 ?543次閱讀

    IEEE新突破:數學解法引領光子晶體激光器創新

    反饋”)來增強光強度。當光的強度達到所需的增益后,激光二極管就會釋放出強大的激光束。光子晶體表面發射激光器(PCSELs)作為先進的激光二極管,它的光學增益主要沿著光在光子晶體(PC)結構的傳播方向分布。與傳統激光器不同,PCSELs能
    的頭像 發表于 02-20 09:16 ?563次閱讀

    使用HAL庫寫無人機遙控器的串口時,串口沒有反應,NRF24L01無法和飛控進行通信

    使用串口1 已排除硬件問題(使用其他標準庫的串口文件測試printf輸出顯示沒有問題) 且使用keil5的邏輯分析儀讀取CSN引腳有波形顯示 找了幾天沒找出來這個問題的解法*附件:F1_Remote_1.0.zip
    發表于 01-27 23:08

    ADC14L040的內部有保護電路嗎?

    各位大蝦同仁們,小弟設計了一個ADC14L040的電路,按照數據手冊,其參考電壓應該是1V(我用的是內部參考,電路解法基本參照手冊),可是在實測為1.5V的直流參考,請問這是為什么?還有,ADC14L040的內部有保護電路嗎,當我的輸入峰峰值超過4V時,采集出來的數據
    發表于 01-08 07:47

    一文了解法蘭密封泄漏的原因

    今天小編和大家聊聊法蘭密封泄露的原因。 法蘭密封一般是依靠其連接螺栓所產生的預緊力,通過各種固體墊片(如:橡膠、石棉橡膠墊片、植物纖維墊片、纏繞式金屬內填石棉墊片、波紋狀金屬內填石棉墊片、波紋狀金屬夾殼內填石棉墊片、波紋狀金屬墊片、平金屬夾殼內填石棉墊片、槽形金屬墊片、突心金屬平墊片、金屬圓環墊片、金屬八角墊片等)或液體墊片(一定時間或一定條件下轉變成一定形狀的固體墊片)達到足夠的工作密封比壓,來阻止被密封
    的頭像 發表于 01-07 09:17 ?535次閱讀
    一文了<b class='flag-5'>解法</b>蘭密封泄漏的原因

    基于FPGA實現圖像直方圖設計

    直方圖統計的原理 直方圖統計從數學上來說,是對圖像的像素點進行統計。圖像直方圖統計常用于統計灰度圖像,表示
    的頭像 發表于 12-24 10:24 ?760次閱讀
    基于FPGA實現<b class='flag-5'>圖像</b>直方圖設計

    DFT在圖像處理的作用 DFT在音頻信號處理的應用

    DFT在圖像處理的作用 離散傅里葉變換(Discrete Fourier Transform,簡稱DFT)是一種將信號從時域轉換到頻域的數學工具,它在圖像處理領域有著廣泛的應用。以下
    的頭像 發表于 12-20 09:18 ?1237次閱讀

    傅立葉變換在圖像處理的作用

    傅里葉變換在圖像處理中發揮著至關重要的作用。以下是傅里葉變換在圖像處理的幾個主要作用: 一、圖像增強與去噪 去噪 :圖像
    的頭像 發表于 12-06 16:55 ?2253次閱讀

    安泰功率放大器在超聲霧化熱解法納米薄膜制備當中應用

    霧化研究,也有著良好應用,今天Aigtek安泰電子就帶大家了解一下功率放大器在超聲霧化熱解法納米薄膜制備當中應用。 針對有機半導體粉料和金屬粉料蒸發溫度低的特點,設計并制作了新型低溫輻射式薄膜加熱蒸發器,通過對有機
    的頭像 發表于 11-19 11:49 ?488次閱讀
    安泰功率放大器在超聲霧化熱<b class='flag-5'>解法</b>納米薄膜制備當中應用

    TPA3116D2/TPA3118D2 2.1的左右聲道,是否需要在前級把低頻部分濾除掉?

    按照datasheet的解法實現2.1聲道,一片做左右聲道,另一片做重低音,如下圖: 本人沒做過音頻方面的東西,對2.1不是很了解,現在有如下幾個問題: 1、2.1的左右聲道,是否需要在前級把
    發表于 10-31 08:00

    華工激光推出新一代輪胎模具在線式激光清洗智能裝備

    雙碳目標下,激光清洗正憑借其效率高、精確可控、綠色環保的特點廣泛應用于輪胎、新能源、船舶等行業,成為傳統清洗市場的新解法
    的頭像 發表于 09-06 10:40 ?942次閱讀

    為什么有些TINA-TI仿真可以實現穩態求解法分析,而有些不行?

    為什么有些TINA-TI仿真可以實現穩態求解法分析,而有些不行,出現提示: ,無法執行穩態分析。 是有什么區別嗎?還是哪里需要設置嗎?
    發表于 08-08 08:28

    OpenCV圖像識別C++代碼

    的頭文件 在您的C++代碼,包含以下必要的頭文件: # include # include # include # include # include # include # include 讀取圖像
    的頭像 發表于 07-16 10:42 ?4483次閱讀

    圖像處理的卷積運算

    卷積運算是圖像處理中一種極其重要的操作,廣泛應用于圖像濾波、邊緣檢測、特征提取等多個方面。它基于一個核(或稱為卷積核、濾波器)與圖像進行相乘并求和的過程,通過這一操作可以實現對圖像的平
    的頭像 發表于 07-11 15:15 ?3914次閱讀
    主站蜘蛛池模板: 亚洲理论片 | 天天久久综合 | 人人揉揉香蕉大青草 | 美女网站视频色 | 婷婷开心六月久久综合丁香 | 玖玖爱这里只有精品 | 国产精品免费一级在线观看 | 美女视频网站色 | 美国一级大黄香蕉片 | 国产精品女仆装在线播放 | 特级做a爰片毛片免费看 | 亚洲一区二区三区高清视频 | 亚洲人成人77777网站 | 深夜释放自己vlog糖心旧版本 | 农村妇女色又黄一级毛片卡 | 日本电影在线观看黄 | 日本国产黄色片 | 天天干天天草天天射 | 免费两性的视频网站 | 午夜色站| 午夜在线播放视频在线观看视频 | 最近最新中文字幕在线第一页 | 午夜黄色大片 | 中文字幕在线一区二区在线 | 涩涩涩综合在线亚洲第一 | 免费观看理论片毛片 | 丁香花在线视频观看免费 | 亚洲一区二区三区高清 | 天天综合天天 | 丁香六月综合激情 | 99久久99这里只有免费费精品 | 午夜毛片不卡高清免费 | 天天在线干 | 欧美高清一级片 | 关晓彤被调教出奶水的视频 | 在线观看黄色网 | 欧美啪啪小视频 | 欧美xxxxx精品| 高清影院在线欧美人色 | 看视频免费 | 国产精品免费久久 |