热议:【技术积累】算法中的贪心算法【三】
时间:2023-06-25 17:34:50来源:博客园

贪心算法解决最短超级字符串问题

问题描述

给定一个字符串数组,要求找出一个最短的超级字符串,即包含所有字符串的字符串,并且每个字符串仅出现一次。


(资料图片)

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

输出:"abcde"

解题思路

1. 将给定的字符串数组按照长度从大到小排序,记为strings。2. 定义一个数组visited,用于记录每个字符串是否被访问过,初始值都为false。3. 定义一个变量result,用于记录最终的最短超级字符串,初始值为空字符串。4. 从第一个字符串开始遍历strings数组: a. 如果当前字符串已经被访问过,跳过该字符串。 b. 将当前字符串添加到result中,并将visited数组中对应位置设为true。 c. 从当前字符串的末尾开始,找到strings数组中还未访问过的字符串中最长的公共后缀,将其添加到result中,更新visited数组。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个待完成的工作,每个工作有一个开始时间和一个结束时间,要求找出一个最佳的工作序列,使得这些工作能够顺利完成,且尽可能多的工作能够被完成。

解题思路

1. 将给定的工作列表按照结束时间从小到大排序。2. 定义一个变量result,用于记录最终选择的最佳工作序列,初始为空序列。3. 选择第一个工作,将其加入result中。4. 从第二个工作开始遍历工作列表: a. 如果当前工作的开始时间在上一个工作的结束时间之后,说明可以选择该工作,将其加入result中。 b. 更新上一个工作为当前工作。5. 遍历完所有工作后,result中存储的就是最佳的工作序列。

伪代码

function findBestJobSequence(jobs):    // 按照结束时间从小到大排序    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

注意:此处假设输入的工作列表是类似结构的数据,包含每个工作的开始时间和结束时间的信息,可以根据实际需求进行修改。

贪心算法解决最优加油问题

问题描述

在一条道路上有一辆汽车,道路的长度为L。汽车的油箱容量为C,初始时汽车油箱为空。汽车需要从起点到终点,期间会遇到N个加油站,每个加油站距离起点的距离为d,每个加油站可加油量为v。要求找到一个最优的加油方案,使得汽车能够顺利到达终点,且加油次数最少。

解题思路

1. 定义一个变量tank,用于存储汽车的当前油量,初始值为0。2. 定义一个变量count,用于存储加油次数,初始值为0。3. 定义一个变量currDistance,用于存储当前汽车到达的距离,初始值为0。4. 初始化一个最大堆maxHeap,用于存储可选的加油站,按照加油量v进行排序。5. 遍历加油站集合: a. 将当前加油站加入最大堆maxHeap。 b. 如果汽车的油量tank不足以到达当前加油站,且最大堆maxHeap不为空: - 从最大堆maxHeap中取出一个加油站,记为station。 - 计算需要从上一个加油站到达当前加油站所需的油量,记为requiredGas = station.distance - currDistance。 - 如果requiredGas大于汽车的油量tank,则无法到达当前加油站,返回-1。 - 将汽车的油量tank加上requiredGas,并将计数器count加1,表示加了一次油。 - 更新当前汽车到达的距离currDistance为当前加油站的距离。 c. 如果汽车的油量tank仍然不足以到达终点,则无法顺利到达终点,返回-1。6. 返回计数器count,表示最少的加油次数。

伪代码

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

注意:此处假设输入的加油站集合是一个类似结构的数据,包含每个加油站的距离和可加油量的信息,可以根据实际需求进行修改。

贪心算法解决硬币问题

算法问题描述:给定一个金额amount和一系列面额不同的硬币,要求用最少的硬币组合来凑成amount,并返回硬币的数量。假设有足够数量的每种硬币。

样例输入输出:输入:amount = 11, coins = [1, 2, 5]输出:3

解题思路:1. 初始化一个变量count,用于记录所需的硬币数量。2. 对面额数组coins进行降序排序,方便贪心选择。3. 遍历coins数组,记当前的硬币面额为coin。4. 若当前硬币面额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

说明:在此问题中,通过贪心选择每次选择最大面额的硬币,因为硬币的面额是固定的,所以这是一个可以使用贪心算法解决的合适情况。由于要求找出最少的硬币数量,因此我们先选择面额最大的硬币是最优的选择。然后逐步减少amount,直到amount变为0。注意,这里贪心选择可能不是全局最优解,但在这个问题中,贪心选择是可以得到最优解的。

贪心算法解决射击游戏问题

问题描述:

在一个射击游戏中,玩家需要射击一些不同颜色的气球。每个气球都有一个指定的得分值和一个爆炸半径。假设玩家的射击点是一个二维平面上的坐标(x, y),当玩家发射子弹到该点时,子弹会以该点为中心形成一个爆炸范围。任何与爆炸范围相交的气球都会被击中。玩家的得分等于所有被击中气球的得分值之和。现在,给定一些气球的坐标、得分值和爆炸半径,需要确定玩家应该选择哪个射击点来使得得分最大化。

样例输入输出:

输入:气球列表:[(1,2,3), (2,5,4), (3,1,2), (4,9,5)]描述:[气球的坐标(x, y),得分值,爆炸半径]

输出:最大得分值:14 (通过击中(1,2)和(2,5)这两个气球)

解题思路:

1. 创建一个空集合visited来保存已击中的气球。2. 遍历气球列表,每次选择得分值最高的气球,并将其加入visited集合。3. 定义一个函数is_overlap用来判断两个气球是否有重叠的爆炸范围。两个气球的距离小于等于它们的爆炸半径之和时,表示它们有重叠。4. 在遍历气球列表的过程中,检查当前气球与visited集合中的气球是否有重叠的爆炸范围。若有重叠,则选择得分值更高的气球加入visited集合,替代原有的气球。5. 遍历完所有气球后,visited集合中保存的即为玩家应该击中的气球。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)

贪心算法解决数组重组问题

算法问题描述:

给定一个整数数组nums,现在需要将数组中的元素重新排列,使得任意两个相邻的元素之间的差的绝对值尽可能大。请实现一个函数,返回重组后的数组。注意,重组后的数组可能不是唯一的,只需返回任意一个满足条件的数组即可。

样例输入输出:

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

解题思路:

1. 对数组进行排序,从小到大。2. 创建一个空的结果数组result[],并将排序后的第一个元素nums[0]加入result[]。3. 从第二个元素开始遍历排序后的数组,逐个将元素插入result[]。4. 奇数索引位置上的元素应该尽量取较大的值,所以将当前元素插入result[]的奇数索引位置。5. 偶数索引位置上的元素应该尽量取较小的值,所以将当前元素插入result[]的偶数索引位置。6. 遍历完所有元素后,result[]即为重组后的数组。

伪代码:

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: // 偶数索引位置            result.insert(i, sorted_nums[i])        else: // 奇数索引位置            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]

贪心算法解决左右两边元素和相等问题

算法问题描述:

给定一个整数数组nums,现在需要判断是否存在一个索引,使得索引左边的元素之和等于索引右边的元素之和。如果存在这样的索引,返回True;否则,返回False。

样例输入输出:

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

解题思路:

1. 遍历数组,计算数组中所有元素的和,得到总和total。2. 初始化左侧元素之和left_sum为0。3. 从左到右遍历数组,每次将当前元素加入左侧元素之和left_sum,同时将总和total减去当前元素。4. 在遍历的过程中,检查左侧元素之和left_sum是否等于右侧元素之和total减去当前元素的值。若相等,表示存在满足条件的索引,返回True。5. 若遍历完所有元素后仍未找到满足条件的索引,则返回False。

伪代码:

function equal_sum(nums):    total = sum(nums)    left_sum = 0        for i in range(len(nums)):        total -= nums[i] // 将总和减去当前元素        if left_sum == total:            return True        left_sum += nums[i] // 将当前元素加入左侧元素之和        return False// 测试nums = [1, 7, 3, 6, 5, 6]has_equal_sum = equal_sum(nums)print(has_equal_sum)

输出:True

贪心算法解决图着色问题

算法问题描述

给定一个无向图,图的顶点由一个整数标识,图的边由一个无序的顶点对表示。要求为图的每个顶点分配一个颜色,同时要求相邻的顶点不能有相同的颜色。现在需要设计一个算法,使用贪心算法解决图着色问题,即找到符合要求的最小颜色数量。

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. 创建一个字典colors,用于存储每个顶点的颜色值。初始时,将所有顶点的颜色初始化为-1,表示未分配颜色。2. 对图中的每个顶点进行遍历,对于每个顶点v,执行以下操作: 1) 创建一个集合used_colors,用于存储v的邻接顶点已经使用的颜色值。 2) 遍历v的邻接顶点,将颜色值加入到used_colors集合中。 3) 遍历颜色值1到无穷大的整数,找到一个未被used_colors集合包含的最小整数,将此整数作为v的颜色值。3. 返回字典colors中颜色值的种类数量。

伪代码:

function graphColoring(graph):    colors = {}  // 创建一个字典,存储每个顶点的颜色    for each vertex v in graph:        used_colors = set()  // 创建集合,存储v的邻接顶点已分配的颜色值        for each adjacent_vertex in v.adjacent_vertices:            if colors[adjacent_vertex] != -1:  // 如果邻接顶点已分配颜色                used_colors.add(colors[adjacent_vertex])        for color in range(1, infinity):  // 从1到无穷大的整数            if color not in used_colors:  // 找到一个未被邻接顶点使用的最小颜色                colors[v] = color                break    return number of distinct colors in colors

其中,graph表示输入的无向图,每个顶点的颜色值存储在字典colors中。最后,返回colors中不同颜色值的数量。

标签:

最新
  • 热议:【技术积累】算法中的贪心算法【三】

    博客推行版本更新,成果积累制度,已经写过的博客还会再次更新,不断地

  • 陶瓷釉是什么材料做成的 陶瓷釉涂层有害健康吗? 环球观热点

    想必现在有很多小伙伴对于陶瓷釉是什么材料做成的是什么方面的知识

  • 每日资讯:怀孕早期是会发低烧吗_怀孕会发低烧吗

    1、病情分析:怀孕可能引起低烧,这是不正常的。2、孕期低烧要注意。3

  • 今头条!九江:建好安置房,筑起“安居梦”

    九江新闻网讯(九江日报全媒记者  刘家  摄)近日,在八里湖东组团

  • 王大陆蔡卓宜分手了吗?双方取关账号删除合影,女方发文情绪低落 环球今亮点

    王大陆蔡卓宜分手了吗?双方取关账号删除合影,女方发文情绪低落

  • 世界今日讯!真的可以每日白嫖的csgo开箱网站有哪些?常见的csgo玄学皮肤有哪些?

    csgo玄学皮肤有哪些多普勒,蛊惑之色,远光灯,猫猫狗狗,影魔,城

  • 端午出行热度高 节前晚高峰每分钟超10万人同时打车 精选

    6月24日,进入端午小长假尾声。记者从滴滴出行了解到,今年端午假期,

  • 焦点短讯!通讯!欧盟通过第11轮对俄制裁,俄外交部:制裁非法,已及时回应

    当地时间6月23日,俄罗斯外交部发表声明表示,欧盟通过的针对俄罗斯的

  • 广西连日降雨致局地内涝 南宁民众蹚水而行 环球短讯

    6月24日,受强降雨影响,广西南宁市内部分路段出现不同程度的积水内涝

  • 每日热讯!诈骗30万罚金是多少? 当前快播

    一、诈骗30万罚金是多少?根据我国刑法第五十二条判处罚金,应根据犯罪

  • 环球要闻:CXO大跌:没有彻底的崩盘,只有躲不过的周期

    谁也躲不过周期。过去几年,受益于生物科技行业的繁荣发展,下游“卖铲

  • “甜酷”相宜 津夜有滋味

    “甜酷”相宜津夜有滋味(主题)天津日报记者廖晨霞听音乐、品美食、拍

  • 物流技术和供应链实力获赞,京东集团首次入选《时代周刊》全球100大最具影响力企业

    6月21日,《时代周刊》发布“2023年全球100大最具影响力企业”,京东集

  • 快播:江苏连云港:亲水避暑享清凉

    nullnullnullnull2023年6月23日,游客在江苏省连云港市赣榆区海州湾水

  • 当前热点-国家外汇管理局:1-5月中国外汇市场累计成交101.87万亿元人民币

    国家外汇管理局统计数据显示,2023年5月,中国外汇市场(不含外币对市

  • 教育部部署做好2023年普通高校招生录取工作|焦点短讯

    记者6月21日从教育部获悉,2023年普通高校招生录取工作即将开始。教育

  • 旅游
    • 天天观察:美西码头罢工事件影响有限 需求不振班轮公司抬价难支撑

    • 当前热议!笑不活了!AI对表情包下手,张学友周星驰都被玩坏了

    • 畜牧兽医专业包括哪些项目就方向

    • 四川引进重点知名外资项目又添成果_世界快报