【技術(shù)積累】算法中的貪心算法【三】 天天關(guān)注
時(shí)間:2023-06-25 10:00:58
貪心算法解決最短超級(jí)字符串問(wèn)題
問(wèn)題描述
(資料圖片)
給定一個(gè)字符串?dāng)?shù)組,要求找出一個(gè)最短的超級(jí)字符串,即包含所有字符串的字符串,并且每個(gè)字符串僅出現(xiàn)一次。
輸入:["abc", "bcd", "cde"]
輸出:"abcde"
解題思路
1. 將給定的字符串?dāng)?shù)組按照長(zhǎng)度從大到小排序,記為strings。2. 定義一個(gè)數(shù)組visited,用于記錄每個(gè)字符串是否被訪問(wèn)過(guò),初始值都為false。3. 定義一個(gè)變量result,用于記錄最終的最短超級(jí)字符串,初始值為空字符串。4. 從第一個(gè)字符串開(kāi)始遍歷strings數(shù)組: a. 如果當(dāng)前字符串已經(jīng)被訪問(wèn)過(guò),跳過(guò)該字符串。 b. 將當(dāng)前字符串添加到result中,并將visited數(shù)組中對(duì)應(yīng)位置設(shè)為true。 c. 從當(dāng)前字符串的末尾開(kāi)始,找到strings數(shù)組中還未訪問(wèn)過(guò)的字符串中最長(zhǎng)的公共后綴,將其添加到result中,更新visited數(shù)組。5. 遍歷完所有字符串后,result中存儲(chǔ)的就是最短超級(jí)字符串。
偽代碼
function findShortestSuperstring(strings): // 按照長(zhǎng)度從大到小排序 sort(strings, descending order of length) // 記錄每個(gè)字符串是否被訪問(wèn) visited = new Array(strings.length, false) // 存儲(chǔ)最短超級(jí)字符串 result = "" for i from 1 to strings.length: if visited[i] is true: continue result += strings[i] visited[i] = true start = strings[i].length while start > 0: maxLen = 0 maxIdx = -1 for j from 0 to strings.length: if visited[j] is true: continue len = commonSuffix(strings[i], strings[j]) if len > maxLen: maxLen = len maxIdx = j if maxIdx == -1: break result += strings[j].substring(maxLen) visited[maxIdx] = true start = strings[maxIdx].length return resultfunction commonSuffix(str1, str2): len1 = str1.length len2 = str2.length len = min(len1, len2) suffix = "" for i from 1 to len: if str1.substring(len1 - i) == str2.substring(0, i): suffix = str2.substring(0, i) return suffix貪心算法解決最佳工作序列問(wèn)題
問(wèn)題描述
有n個(gè)待完成的工作,每個(gè)工作有一個(gè)開(kāi)始時(shí)間和一個(gè)結(jié)束時(shí)間,要求找出一個(gè)最佳的工作序列,使得這些工作能夠順利完成,且盡可能多的工作能夠被完成。
解題思路
1. 將給定的工作列表按照結(jié)束時(shí)間從小到大排序。2. 定義一個(gè)變量result,用于記錄最終選擇的最佳工作序列,初始為空序列。3. 選擇第一個(gè)工作,將其加入result中。4. 從第二個(gè)工作開(kāi)始遍歷工作列表: a. 如果當(dāng)前工作的開(kāi)始時(shí)間在上一個(gè)工作的結(jié)束時(shí)間之后,說(shuō)明可以選擇該工作,將其加入result中。 b. 更新上一個(gè)工作為當(dāng)前工作。5. 遍歷完所有工作后,result中存儲(chǔ)的就是最佳的工作序列。
偽代碼
function findBestJobSequence(jobs): // 按照結(jié)束時(shí)間從小到大排序 sort(jobs, ascending order of end time) // 存儲(chǔ)最佳工作序列 result = [] result.push(jobs[0]) prevJob = jobs[0] for i from 1 to jobs.length: currJob = jobs[i] if currJob.startTime >= prevJob.endTime: result.push(currJob) prevJob = currJob return result注意:此處假設(shè)輸入的工作列表是類(lèi)似結(jié)構(gòu)的數(shù)據(jù),包含每個(gè)工作的開(kāi)始時(shí)間和結(jié)束時(shí)間的信息,可以根據(jù)實(shí)際需求進(jìn)行修改。
貪心算法解決最優(yōu)加油問(wèn)題
問(wèn)題描述
在一條道路上有一輛汽車(chē),道路的長(zhǎng)度為L(zhǎng)。汽車(chē)的油箱容量為C,初始時(shí)汽車(chē)油箱為空。汽車(chē)需要從起點(diǎn)到終點(diǎn),期間會(huì)遇到N個(gè)加油站,每個(gè)加油站距離起點(diǎn)的距離為d,每個(gè)加油站可加油量為v。要求找到一個(gè)最優(yōu)的加油方案,使得汽車(chē)能夠順利到達(dá)終點(diǎn),且加油次數(shù)最少。
解題思路
1. 定義一個(gè)變量tank,用于存儲(chǔ)汽車(chē)的當(dāng)前油量,初始值為0。2. 定義一個(gè)變量count,用于存儲(chǔ)加油次數(shù),初始值為0。3. 定義一個(gè)變量currDistance,用于存儲(chǔ)當(dāng)前汽車(chē)到達(dá)的距離,初始值為0。4. 初始化一個(gè)最大堆maxHeap,用于存儲(chǔ)可選的加油站,按照加油量v進(jìn)行排序。5. 遍歷加油站集合: a. 將當(dāng)前加油站加入最大堆maxHeap。 b. 如果汽車(chē)的油量tank不足以到達(dá)當(dāng)前加油站,且最大堆maxHeap不為空: - 從最大堆maxHeap中取出一個(gè)加油站,記為station。 - 計(jì)算需要從上一個(gè)加油站到達(dá)當(dāng)前加油站所需的油量,記為requiredGas = station.distance - currDistance。 - 如果requiredGas大于汽車(chē)的油量tank,則無(wú)法到達(dá)當(dāng)前加油站,返回-1。 - 將汽車(chē)的油量tank加上requiredGas,并將計(jì)數(shù)器count加1,表示加了一次油。 - 更新當(dāng)前汽車(chē)到達(dá)的距離currDistance為當(dāng)前加油站的距離。 c. 如果汽車(chē)的油量tank仍然不足以到達(dá)終點(diǎn),則無(wú)法順利到達(dá)終點(diǎn),返回-1。6. 返回計(jì)數(shù)器count,表示最少的加油次數(shù)。
偽代碼
function findOptimalRefueling(stations, L, C): tank = 0 count = 0 currDistance = 0 maxHeap = initializeMaxHeap() for each station in stations: addStationToMaxHeap(maxHeap, station) if tank < station.distance - currDistance and !isEmpty(maxHeap): while tank < station.distance - currDistance and !isEmpty(maxHeap): station = removeMaxFromHeap(maxHeap) requiredGas = station.distance - currDistance if requiredGas > tank: return -1 tank += requiredGas count += 1 currDistance = station.distance if tank < station.distance - currDistance: return -1 return count注意:此處假設(shè)輸入的加油站集合是一個(gè)類(lèi)似結(jié)構(gòu)的數(shù)據(jù),包含每個(gè)加油站的距離和可加油量的信息,可以根據(jù)實(shí)際需求進(jìn)行修改。
貪心算法解決硬幣問(wèn)題
算法問(wèn)題描述:給定一個(gè)金額amount和一系列面額不同的硬幣,要求用最少的硬幣組合來(lái)湊成amount,并返回硬幣的數(shù)量。假設(shè)有足夠數(shù)量的每種硬幣。
樣例輸入輸出:輸入:amount = 11, coins = [1, 2, 5]輸出:3
解題思路:1. 初始化一個(gè)變量count,用于記錄所需的硬幣數(shù)量。2. 對(duì)面額數(shù)組coins進(jìn)行降序排序,方便貪心選擇。3. 遍歷coins數(shù)組,記當(dāng)前的硬幣面額為coin。4. 若當(dāng)前硬幣面額coin小于等于amount,則將amount除以coin的商記為numCoins,表示可以使用numCoins個(gè)硬幣coin來(lái)湊成amount。 - 將numCoins加到count中。 - 將amount更新為amount減去numCoins個(gè)硬幣coin的面值。5. 返回count。
偽代碼:
function coinChange(amount, coins) count = 0 sort coins in descending order for coin in coins if coin <= amount then numCoins = amount / coin count = count + numCoins amount = amount - (numCoins * coin) return count說(shuō)明:在此問(wèn)題中,通過(guò)貪心選擇每次選擇最大面額的硬幣,因?yàn)橛矌诺拿骖~是固定的,所以這是一個(gè)可以使用貪心算法解決的合適情況。由于要求找出最少的硬幣數(shù)量,因此我們先選擇面額最大的硬幣是最優(yōu)的選擇。然后逐步減少amount,直到amount變?yōu)?。注意,這里貪心選擇可能不是全局最優(yōu)解,但在這個(gè)問(wèn)題中,貪心選擇是可以得到最優(yōu)解的。
貪心算法解決射擊游戲問(wèn)題
問(wèn)題描述:
在一個(gè)射擊游戲中,玩家需要射擊一些不同顏色的氣球。每個(gè)氣球都有一個(gè)指定的得分值和一個(gè)爆炸半徑。假設(shè)玩家的射擊點(diǎn)是一個(gè)二維平面上的坐標(biāo)(x, y),當(dāng)玩家發(fā)射子彈到該點(diǎn)時(shí),子彈會(huì)以該點(diǎn)為中心形成一個(gè)爆炸范圍。任何與爆炸范圍相交的氣球都會(huì)被擊中。玩家的得分等于所有被擊中氣球的得分值之和?,F(xiàn)在,給定一些氣球的坐標(biāo)、得分值和爆炸半徑,需要確定玩家應(yīng)該選擇哪個(gè)射擊點(diǎn)來(lái)使得得分最大化。
樣例輸入輸出:
輸入:氣球列表:[(1,2,3), (2,5,4), (3,1,2), (4,9,5)]描述:[氣球的坐標(biāo)(x, y),得分值,爆炸半徑]
輸出:最大得分值:14 (通過(guò)擊中(1,2)和(2,5)這兩個(gè)氣球)
解題思路:
1. 創(chuàng)建一個(gè)空集合visited來(lái)保存已擊中的氣球。2. 遍歷氣球列表,每次選擇得分值最高的氣球,并將其加入visited集合。3. 定義一個(gè)函數(shù)is_overlap用來(lái)判斷兩個(gè)氣球是否有重疊的爆炸范圍。兩個(gè)氣球的距離小于等于它們的爆炸半徑之和時(shí),表示它們有重疊。4. 在遍歷氣球列表的過(guò)程中,檢查當(dāng)前氣球與visited集合中的氣球是否有重疊的爆炸范圍。若有重疊,則選擇得分值更高的氣球加入visited集合,替代原有的氣球。5. 遍歷完所有氣球后,visited集合中保存的即為玩家應(yīng)該擊中的氣球。6. 計(jì)算visited集合中氣球的得分值之和,即為最大得分值。
偽代碼:
function is_overlap(ball1, ball2): // 判斷兩個(gè)氣球是否有重疊的爆炸范圍 distance = sqrt((ball1.x - ball2.x)^2 + (ball1.y - ball2.y)^2) return distance <= ball1.radius + ball2.radiusfunction shooting_game(balloons): visited = set() max_score = 0 for i in range(len(balloons)): if i not in visited: // 未被擊中過(guò)的氣球 visited.add(i) max_score += balloons[i].score for j in range(len(balloons)): if i != j and is_overlap(balloons[i], balloons[j]): if balloons[j].score > balloons[i].score: visited.remove(i) max_score -= balloons[i].score visited.add(j) max_score += balloons[j].score return max_score// 測(cè)試balloons = [(1,2,3), (2,5,4), (3,1,2), (4,9,5)]max_score = shooting_game(balloons)print(max_score)貪心算法解決數(shù)組重組問(wèn)題
算法問(wèn)題描述:
給定一個(gè)整數(shù)數(shù)組nums,現(xiàn)在需要將數(shù)組中的元素重新排列,使得任意兩個(gè)相鄰的元素之間的差的絕對(duì)值盡可能大。請(qǐng)實(shí)現(xiàn)一個(gè)函數(shù),返回重組后的數(shù)組。注意,重組后的數(shù)組可能不是唯一的,只需返回任意一個(gè)滿足條件的數(shù)組即可。
樣例輸入輸出:
輸入:[1, 2, 3, 4, 5]輸出:[1, 3, 2, 4, 5]
解題思路:
1. 對(duì)數(shù)組進(jìn)行排序,從小到大。2. 創(chuàng)建一個(gè)空的結(jié)果數(shù)組result[],并將排序后的第一個(gè)元素nums[0]加入result[]。3. 從第二個(gè)元素開(kāi)始遍歷排序后的數(shù)組,逐個(gè)將元素插入result[]。4. 奇數(shù)索引位置上的元素應(yīng)該盡量取較大的值,所以將當(dāng)前元素插入result[]的奇數(shù)索引位置。5. 偶數(shù)索引位置上的元素應(yīng)該盡量取較小的值,所以將當(dāng)前元素插入result[]的偶數(shù)索引位置。6. 遍歷完所有元素后,result[]即為重組后的數(shù)組。
偽代碼:
function rearrange_array(nums): sorted_nums = sort(nums) result = [] result.append(sorted_nums[0]) for i in range(1, len(sorted_nums)): if i % 2 == 0: // 偶數(shù)索引位置 result.insert(i, sorted_nums[i]) else: // 奇數(shù)索引位置 result.append(sorted_nums[i]) return result// 測(cè)試nums = [1, 2, 3, 4, 5]rearranged_nums = rearrange_array(nums)print(rearranged_nums)輸出:[1, 3, 2, 5, 4]
貪心算法解決左右兩邊元素和相等問(wèn)題
算法問(wèn)題描述:
給定一個(gè)整數(shù)數(shù)組nums,現(xiàn)在需要判斷是否存在一個(gè)索引,使得索引左邊的元素之和等于索引右邊的元素之和。如果存在這樣的索引,返回True;否則,返回False。
樣例輸入輸出:
輸入:[1, 7, 3, 6, 5, 6]輸出:True
解題思路:
1. 遍歷數(shù)組,計(jì)算數(shù)組中所有元素的和,得到總和total。2. 初始化左側(cè)元素之和left_sum為0。3. 從左到右遍歷數(shù)組,每次將當(dāng)前元素加入左側(cè)元素之和left_sum,同時(shí)將總和total減去當(dāng)前元素。4. 在遍歷的過(guò)程中,檢查左側(cè)元素之和left_sum是否等于右側(cè)元素之和total減去當(dāng)前元素的值。若相等,表示存在滿足條件的索引,返回True。5. 若遍歷完所有元素后仍未找到滿足條件的索引,則返回False。
偽代碼:
function equal_sum(nums): total = sum(nums) left_sum = 0 for i in range(len(nums)): total -= nums[i] // 將總和減去當(dāng)前元素 if left_sum == total: return True left_sum += nums[i] // 將當(dāng)前元素加入左側(cè)元素之和 return False// 測(cè)試nums = [1, 7, 3, 6, 5, 6]has_equal_sum = equal_sum(nums)print(has_equal_sum)輸出:True
貪心算法解決圖著色問(wèn)題
算法問(wèn)題描述:
給定一個(gè)無(wú)向圖,圖的頂點(diǎn)由一個(gè)整數(shù)標(biāo)識(shí),圖的邊由一個(gè)無(wú)序的頂點(diǎn)對(duì)表示。要求為圖的每個(gè)頂點(diǎn)分配一個(gè)顏色,同時(shí)要求相鄰的頂點(diǎn)不能有相同的顏色?,F(xiàn)在需要設(shè)計(jì)一個(gè)算法,使用貪心算法解決圖著色問(wèn)題,即找到符合要求的最小顏色數(shù)量。
Vertices: [1, 2, 3, 4, 5, 6]Edges: [(1, 2), (1, 3), (2, 4), (3, 4), (4, 5), (5, 6)]
樣例輸入
graph = { 1: [2, 3], 2: [1, 4], 3: [1, 4], 4: [2, 3, 5], 5: [4, 6], 6: [5]}
輸出:3
解題思路:1. 創(chuàng)建一個(gè)字典colors,用于存儲(chǔ)每個(gè)頂點(diǎn)的顏色值。初始時(shí),將所有頂點(diǎn)的顏色初始化為-1,表示未分配顏色。2. 對(duì)圖中的每個(gè)頂點(diǎn)進(jìn)行遍歷,對(duì)于每個(gè)頂點(diǎn)v,執(zhí)行以下操作: 1) 創(chuàng)建一個(gè)集合used_colors,用于存儲(chǔ)v的鄰接頂點(diǎn)已經(jīng)使用的顏色值。 2) 遍歷v的鄰接頂點(diǎn),將顏色值加入到used_colors集合中。 3) 遍歷顏色值1到無(wú)窮大的整數(shù),找到一個(gè)未被used_colors集合包含的最小整數(shù),將此整數(shù)作為v的顏色值。3. 返回字典colors中顏色值的種類(lèi)數(shù)量。
偽代碼:
function graphColoring(graph): colors = {} // 創(chuàng)建一個(gè)字典,存儲(chǔ)每個(gè)頂點(diǎn)的顏色 for each vertex v in graph: used_colors = set() // 創(chuàng)建集合,存儲(chǔ)v的鄰接頂點(diǎn)已分配的顏色值 for each adjacent_vertex in v.adjacent_vertices: if colors[adjacent_vertex] != -1: // 如果鄰接頂點(diǎn)已分配顏色 used_colors.add(colors[adjacent_vertex]) for color in range(1, infinity): // 從1到無(wú)窮大的整數(shù) if color not in used_colors: // 找到一個(gè)未被鄰接頂點(diǎn)使用的最小顏色 colors[v] = color break return number of distinct colors in colors其中,graph表示輸入的無(wú)向圖,每個(gè)頂點(diǎn)的顏色值存儲(chǔ)在字典colors中。最后,返回colors中不同顏色值的數(shù)量。
相關(guān)稿件
【技術(shù)積累】算法中的貪心算法【三】 天天關(guān)注
從“三代種桃人”看現(xiàn)代農(nóng)業(yè)怎么干——算好加減法 做好“一二三”|每日時(shí)訊
云?。骸笆奈濉逼谀┤杏?jì)劃新籌建保租房不少于1000套_世界訊息
今日關(guān)注:黃仁勛稱英偉達(dá)“極有可能”在歐洲投資
我省法檢攜手共促行政爭(zhēng)議實(shí)質(zhì)性化解
端午“買(mǎi)買(mǎi)買(mǎi)”!金價(jià)走低 黃金飾品消費(fèi)熱度高
環(huán)球快播:女孩充電被電擊內(nèi)臟受損面臨截肢 蘋(píng)果官方:適配器非原裝,如果是第三方問(wèn)題,不會(huì)賠償
揚(yáng)州考試錄用公務(wù)員工作 新錄用公務(wù)員645名 全球快播
瓦格納人員撤離俄南部軍區(qū)總部所在區(qū)域 環(huán)球觀點(diǎn)
打印紙產(chǎn)業(yè)深度調(diào)研報(bào)告 打印紙行業(yè)的前景與未來(lái)趨勢(shì)分析2023-環(huán)球即時(shí)看
全球微頭條丨端午假期民航鐵路出行均超2019年水平 拼假出行受歡迎
今熱點(diǎn):【農(nóng)牧飼漁】6月USDA跟蹤月報(bào):6月USDA上調(diào)三大作物產(chǎn)量,持續(xù)關(guān)注厄爾尼諾
【天天播資訊】AMD RX 7800 XT顯卡新爆料,將采用新GPU
銀川燒烤店燃?xì)獗ㄊ鹿试蚬?焦點(diǎn)快報(bào)
跨越2100公里,每年最多向浙江輸送300億千瓦時(shí)的四川水電 一條銀線 千里“閃送”
世界焦點(diǎn)!“家校坊”凝聚起鄉(xiāng)村家校合力
在北京,高中讀韓國(guó)課程國(guó)際學(xué)校怎么樣?
漲不動(dòng)的「房補(bǔ)區(qū)」,悄悄離開(kāi)的互聯(lián)網(wǎng)大廠人_快資訊
經(jīng)常吃哪些水果蔬菜可以養(yǎng)顏美容? 速讀
世界觀焦點(diǎn):贛州白癜風(fēng)醫(yī)院怎么找-患者如何治療自己的白斑才能盡快好轉(zhuǎn)呢?
教育頻道
精彩看點(diǎn):狐廠大拷問(wèn) | 朱一龍:沒(méi)規(guī)劃過(guò)轉(zhuǎn)型,獲得認(rèn)可后更自信松弛
北京地鐵:地鐵10號(hào)線一列車(chē)在分鐘寺站車(chē)載故障,目前故障已修復(fù)_世界球精選
世界新動(dòng)態(tài):端午假期上海迎客672.48萬(wàn)人次,實(shí)現(xiàn)旅游消費(fèi)96.13億元
熱門(mén)看點(diǎn):全球燃油汽車(chē)銷(xiāo)量已經(jīng)達(dá)到峰值了嗎?
當(dāng)前看點(diǎn)!國(guó)鐵集團(tuán):全國(guó)鐵路今日預(yù)計(jì)發(fā)送旅客1515萬(wàn)人次
今日熱搜:2023年安徽高溫補(bǔ)貼發(fā)放標(biāo)準(zhǔn)是怎樣的
白酒進(jìn)入調(diào)整周期?中國(guó)酒業(yè)協(xié)會(huì):短期不樂(lè)觀 長(zhǎng)期不悲觀|新資訊
權(quán)益基金經(jīng)理管理規(guī)模邊界探究:道阻且長(zhǎng) 行則將至


