本专栏旨在通过分类学习算法,使您能够牢固掌握不同算法的理论要点。通过策略性地练习精选的经典题目,帮助您深度理解每种算法,避免出现刷了很多算法题,还是一知半解的状态
贪心算法(Greedy Algorithm)是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法策略。
贪心算法在有最优子结构的问题中尤其有效,这种子结构意味着局部最优解能决定全局最优解。简单地说,一个问题的最优解包含其子问题的最优解。贪心算法不一定能求得所有问题的全局最优解,因为它通常没有考虑前面的选择如何影响后面的选择(即它不回溯)。但在很多情况下,贪心算法可以产生最优解或接近最优的解。
贪心算法的步骤通常如下:
建立数学模型:将问题抽象为数学模型。
定义选择过程:明确每一步如何选择最优解。
证明局部最优能导致全局最优:这是使用贪心算法的关键,需要证明每一步的局部最优解能最终合成全局最优解。
构建算法:根据定义的模型和选择过程来实现算法。
求解并验证:运行算法求解,然后验证算法的正确性和效率。
贪心算法常用于解决优化问题,例如:
以下是一个简单的贪心算法示例,解决找零问题:
def coin_change(coins, amount):
coins.sort(reverse=True) # 将硬币从大到小排序
num_coins = 0
for coin in coins:
if amount <= 0:
break
num_coins += amount // coin
amount %= coin
return num_coins if amount == 0 else -1 # 如果无法正好找零,返回-1
# 示例
coins = [25, 10, 5, 1]
amount = 63
print(coin_change(coins, amount)) # 输出应该是找零所需的最少硬币数
在这个例子中,算法从最大的硬币开始,尽可能多地使用大硬币,然后逐渐使用更小的硬币,直到找零完成。这个特定问题的贪心策略能够得到最优解,因为硬币的面额都是彼此的倍数。然而对于不是倍数关系的面额,贪心策略可能就无法得到最优解了。因此,使用贪心算法时,需要根据问题的具体情况来判断其适用性。
给定一个包含大写字母和小写字母的字符串 s ,返回 通过这些字母构造成的 最长的回文串 。
在构造过程中,请注意 区分大小写 。比如 “Aa” 不能当做一个回文字符串。
示例 1:
输入:s = “abccccdd”
输出:7
解释: 我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。
示例 2:
输入:s = “a”
输出:1
示例 3:
输入:s = “aaaaaccc”
输出:7
提示:
1 <= s.length <= 2000
s 只由小写 和/或 大写英文字母组成
官方题解
给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。
每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:
返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]。
示例 1:
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
示例 2:
输入: nums = [2,3,0,1,4]
输出: 2
提示:
1 <= nums.length <= 104
0 <= nums[i] <= 1000
题目保证可以到达 nums[n-1]
官方题解
给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。
在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
示例 1:
输入:prices = [7,1,5,3,6,4]
输出:7
解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3 。
总利润为 4 + 3 = 7 。
示例 2:
输入:prices = [1,2,3,4,5]
输出:4
解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
总利润为 4 。
示例 3:
输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为 0 。
提示:
1 <= prices.length <= 3 * 104
0 <= prices[i] <= 104
官方题解