国产精品久久99,51久久成人国产精品麻豆,亚洲欧洲免费三级网站,最近中文字幕mv,重口老太大和小伙乱

首頁>科技 > 正文

【技術(shù)積累】算法中的貪心算法【三】

2023-06-25 09:38:51來源:博客園

貪心算法解決最短超級字符串問題

問題描述

給定一個字符串?dāng)?shù)組,要求找出一個最短的超級字符串,即包含所有字符串的字符串,并且每個字符串僅出現(xiàn)一次。


(資料圖)

輸入:["abc", "bcd", "cde"]

輸出:"abcde"

解題思路

1. 將給定的字符串?dāng)?shù)組按照長度從大到小排序,記為strings。2. 定義一個數(shù)組visited,用于記錄每個字符串是否被訪問過,初始值都為false。3. 定義一個變量result,用于記錄最終的最短超級字符串,初始值為空字符串。4. 從第一個字符串開始遍歷strings數(shù)組: a. 如果當(dāng)前字符串已經(jīng)被訪問過,跳過該字符串。 b. 將當(dāng)前字符串添加到result中,并將visited數(shù)組中對應(yīng)位置設(shè)為true。 c. 從當(dāng)前字符串的末尾開始,找到strings數(shù)組中還未訪問過的字符串中最長的公共后綴,將其添加到result中,更新visited數(shù)組。5. 遍歷完所有字符串后,result中存儲的就是最短超級字符串。

偽代碼

function findShortestSuperstring(strings):    // 按照長度從大到小排序    sort(strings, descending order of length)        // 記錄每個字符串是否被訪問    visited = new Array(strings.length, false)        // 存儲最短超級字符串    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

貪心算法解決最佳工作序列問題

問題描述

有n個待完成的工作,每個工作有一個開始時間和一個結(jié)束時間,要求找出一個最佳的工作序列,使得這些工作能夠順利完成,且盡可能多的工作能夠被完成。

解題思路

1. 將給定的工作列表按照結(jié)束時間從小到大排序。2. 定義一個變量result,用于記錄最終選擇的最佳工作序列,初始為空序列。3. 選擇第一個工作,將其加入result中。4. 從第二個工作開始遍歷工作列表: a. 如果當(dāng)前工作的開始時間在上一個工作的結(jié)束時間之后,說明可以選擇該工作,將其加入result中。 b. 更新上一個工作為當(dāng)前工作。5. 遍歷完所有工作后,result中存儲的就是最佳的工作序列。

偽代碼

function findBestJobSequence(jobs):    // 按照結(jié)束時間從小到大排序    sort(jobs, ascending order of end time)        // 存儲最佳工作序列    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è)輸入的工作列表是類似結(jié)構(gòu)的數(shù)據(jù),包含每個工作的開始時間和結(jié)束時間的信息,可以根據(jù)實(shí)際需求進(jìn)行修改。

貪心算法解決最優(yōu)加油問題

問題描述

在一條道路上有一輛汽車,道路的長度為L。汽車的油箱容量為C,初始時汽車油箱為空。汽車需要從起點(diǎn)到終點(diǎn),期間會遇到N個加油站,每個加油站距離起點(diǎn)的距離為d,每個加油站可加油量為v。要求找到一個最優(yōu)的加油方案,使得汽車能夠順利到達(dá)終點(diǎn),且加油次數(shù)最少。

解題思路

1. 定義一個變量tank,用于存儲汽車的當(dāng)前油量,初始值為0。2. 定義一個變量count,用于存儲加油次數(shù),初始值為0。3. 定義一個變量currDistance,用于存儲當(dāng)前汽車到達(dá)的距離,初始值為0。4. 初始化一個最大堆maxHeap,用于存儲可選的加油站,按照加油量v進(jìn)行排序。5. 遍歷加油站集合: a. 將當(dāng)前加油站加入最大堆maxHeap。 b. 如果汽車的油量tank不足以到達(dá)當(dāng)前加油站,且最大堆maxHeap不為空: - 從最大堆maxHeap中取出一個加油站,記為station。 - 計算需要從上一個加油站到達(dá)當(dāng)前加油站所需的油量,記為requiredGas = station.distance - currDistance。 - 如果requiredGas大于汽車的油量tank,則無法到達(dá)當(dāng)前加油站,返回-1。 - 將汽車的油量tank加上requiredGas,并將計數(shù)器count加1,表示加了一次油。 - 更新當(dāng)前汽車到達(dá)的距離currDistance為當(dāng)前加油站的距離。 c. 如果汽車的油量tank仍然不足以到達(dá)終點(diǎn),則無法順利到達(dá)終點(diǎn),返回-1。6. 返回計數(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è)輸入的加油站集合是一個類似結(jié)構(gòu)的數(shù)據(jù),包含每個加油站的距離和可加油量的信息,可以根據(jù)實(shí)際需求進(jìn)行修改。

貪心算法解決硬幣問題

算法問題描述:給定一個金額amount和一系列面額不同的硬幣,要求用最少的硬幣組合來湊成amount,并返回硬幣的數(shù)量。假設(shè)有足夠數(shù)量的每種硬幣。

樣例輸入輸出:輸入:amount = 11, coins = [1, 2, 5]輸出:3

解題思路:1. 初始化一個變量count,用于記錄所需的硬幣數(shù)量。2. 對面額數(shù)組coins進(jìn)行降序排序,方便貪心選擇。3. 遍歷coins數(shù)組,記當(dāng)前的硬幣面額為coin。4. 若當(dāng)前硬幣面額coin小于等于amount,則將amount除以coin的商記為numCoins,表示可以使用numCoins個硬幣coin來湊成amount。 - 將numCoins加到count中。 - 將amount更新為amount減去numCoins個硬幣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

說明:在此問題中,通過貪心選擇每次選擇最大面額的硬幣,因?yàn)橛矌诺拿骖~是固定的,所以這是一個可以使用貪心算法解決的合適情況。由于要求找出最少的硬幣數(shù)量,因此我們先選擇面額最大的硬幣是最優(yōu)的選擇。然后逐步減少amount,直到amount變?yōu)?。注意,這里貪心選擇可能不是全局最優(yōu)解,但在這個問題中,貪心選擇是可以得到最優(yōu)解的。

貪心算法解決射擊游戲問題

問題描述:

在一個射擊游戲中,玩家需要射擊一些不同顏色的氣球。每個氣球都有一個指定的得分值和一個爆炸半徑。假設(shè)玩家的射擊點(diǎn)是一個二維平面上的坐標(biāo)(x, y),當(dāng)玩家發(fā)射子彈到該點(diǎn)時,子彈會以該點(diǎn)為中心形成一個爆炸范圍。任何與爆炸范圍相交的氣球都會被擊中。玩家的得分等于所有被擊中氣球的得分值之和。現(xiàn)在,給定一些氣球的坐標(biāo)、得分值和爆炸半徑,需要確定玩家應(yīng)該選擇哪個射擊點(diǎn)來使得得分最大化。

樣例輸入輸出:

輸入:氣球列表:[(1,2,3), (2,5,4), (3,1,2), (4,9,5)]描述:[氣球的坐標(biāo)(x, y),得分值,爆炸半徑]

輸出:最大得分值:14 (通過擊中(1,2)和(2,5)這兩個氣球)

解題思路:

1. 創(chuàng)建一個空集合visited來保存已擊中的氣球。2. 遍歷氣球列表,每次選擇得分值最高的氣球,并將其加入visited集合。3. 定義一個函數(shù)is_overlap用來判斷兩個氣球是否有重疊的爆炸范圍。兩個氣球的距離小于等于它們的爆炸半徑之和時,表示它們有重疊。4. 在遍歷氣球列表的過程中,檢查當(dāng)前氣球與visited集合中的氣球是否有重疊的爆炸范圍。若有重疊,則選擇得分值更高的氣球加入visited集合,替代原有的氣球。5. 遍歷完所有氣球后,visited集合中保存的即為玩家應(yīng)該擊中的氣球。6. 計算visited集合中氣球的得分值之和,即為最大得分值。

偽代碼:

function is_overlap(ball1, ball2):    // 判斷兩個氣球是否有重疊的爆炸范圍    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:  // 未被擊中過的氣球            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// 測試balloons = [(1,2,3), (2,5,4), (3,1,2), (4,9,5)]max_score = shooting_game(balloons)print(max_score)

貪心算法解決數(shù)組重組問題

算法問題描述:

給定一個整數(shù)數(shù)組nums,現(xiàn)在需要將數(shù)組中的元素重新排列,使得任意兩個相鄰的元素之間的差的絕對值盡可能大。請實(shí)現(xiàn)一個函數(shù),返回重組后的數(shù)組。注意,重組后的數(shù)組可能不是唯一的,只需返回任意一個滿足條件的數(shù)組即可。

樣例輸入輸出:

輸入:[1, 2, 3, 4, 5]輸出:[1, 3, 2, 4, 5]

解題思路:

1. 對數(shù)組進(jìn)行排序,從小到大。2. 創(chuàng)建一個空的結(jié)果數(shù)組result[],并將排序后的第一個元素nums[0]加入result[]。3. 從第二個元素開始遍歷排序后的數(shù)組,逐個將元素插入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// 測試nums = [1, 2, 3, 4, 5]rearranged_nums = rearrange_array(nums)print(rearranged_nums)

輸出:[1, 3, 2, 5, 4]

貪心算法解決左右兩邊元素和相等問題

算法問題描述:

給定一個整數(shù)數(shù)組nums,現(xiàn)在需要判斷是否存在一個索引,使得索引左邊的元素之和等于索引右邊的元素之和。如果存在這樣的索引,返回True;否則,返回False。

樣例輸入輸出:

輸入:[1, 7, 3, 6, 5, 6]輸出:True

解題思路:

1. 遍歷數(shù)組,計算數(shù)組中所有元素的和,得到總和total。2. 初始化左側(cè)元素之和left_sum為0。3. 從左到右遍歷數(shù)組,每次將當(dāng)前元素加入左側(cè)元素之和left_sum,同時將總和total減去當(dāng)前元素。4. 在遍歷的過程中,檢查左側(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// 測試nums = [1, 7, 3, 6, 5, 6]has_equal_sum = equal_sum(nums)print(has_equal_sum)

輸出:True

貪心算法解決圖著色問題

算法問題描述

給定一個無向圖,圖的頂點(diǎn)由一個整數(shù)標(biāo)識,圖的邊由一個無序的頂點(diǎn)對表示。要求為圖的每個頂點(diǎn)分配一個顏色,同時要求相鄰的頂點(diǎn)不能有相同的顏色?,F(xiàn)在需要設(shè)計一個算法,使用貪心算法解決圖著色問題,即找到符合要求的最小顏色數(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)建一個字典colors,用于存儲每個頂點(diǎn)的顏色值。初始時,將所有頂點(diǎn)的顏色初始化為-1,表示未分配顏色。2. 對圖中的每個頂點(diǎn)進(jìn)行遍歷,對于每個頂點(diǎn)v,執(zhí)行以下操作: 1) 創(chuàng)建一個集合used_colors,用于存儲v的鄰接頂點(diǎn)已經(jīng)使用的顏色值。 2) 遍歷v的鄰接頂點(diǎn),將顏色值加入到used_colors集合中。 3) 遍歷顏色值1到無窮大的整數(shù),找到一個未被used_colors集合包含的最小整數(shù),將此整數(shù)作為v的顏色值。3. 返回字典colors中顏色值的種類數(shù)量。

偽代碼:

function graphColoring(graph):    colors = {}  // 創(chuàng)建一個字典,存儲每個頂點(diǎn)的顏色    for each vertex v in graph:        used_colors = set()  // 創(chuàng)建集合,存儲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到無窮大的整數(shù)            if color not in used_colors:  // 找到一個未被鄰接頂點(diǎn)使用的最小顏色                colors[v] = color                break    return number of distinct colors in colors

其中,graph表示輸入的無向圖,每個頂點(diǎn)的顏色值存儲在字典colors中。最后,返回colors中不同顏色值的數(shù)量。

關(guān)鍵詞:

責(zé)任編輯:

免責(zé)聲明

頭條新聞

精彩推送

新聞推送