目录
贪心策略
概念
思路
算法考题
贪心策略的百度解释是:
在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解 。
贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择 。
基本上所有的贪心算法都可以用回溯来解决(全排列),就是说如果真的想不到好的贪心策略去实现,全排列也可以解决这个算法问题,只是时间复杂度会非常高(>O(n!) && 所以说贪心是一种优化算法,是在已经能解决问题的基础上,对题目本身的底层逻辑进行分析,之后找到优化策略去优化算法的时间复杂度。 贪心算法其实并没有严格意义上的解题思路 如何证明贪心策略是正确的呢?任何贪心策略的提出都是先提出再证明。先使用全排列的方法获取正确答案,再和贪心策略获得的结果进行比较,如果不等说明贪心策略出现错误 字典序最小 题目 给定一个由字符串组成的数组strs,必须把所有的字符串拼接起来,返回所有拼接结果中,字典序最小的结果。 示例 1: 思路 贪心策略: 代码 类似题目 零钱问题 题目 lintcode:1546. 零钱问题 小明是一个销售员,客人在他的地方买了东西,付给了小明一定面值的钱之后,小明需要把多余的钱退给客人。客人付给了小明n,小明的东西的售价为m,小明能退回给客人的面额只能为[100,50,20,10,5,2,1]的组合。现在小明想要使找出去纸币张数最小,请返回这个最小值。 示例 1: 思路 策略: 代码 类似题目 股票问题(最多持有一支,可以买卖无限次) 题目 leetcode:122. 买卖股票的最佳时机 II 给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。 在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。 返回 你能获得的 最大 利润 。 示例 1: 示例 2: 示例 3: 提示: 解析 分析: 思路: 代码 小船过河 题目 leetcode:881. 救生艇 给定数组 people 。people[i]表示第 i 个人的体重 ,船的数量不限,每艘船可以承载的最大重量为 limit。 每艘船最多可同时载两人,但条件是这些人的重量之和最多为 limit。 返回 承载所有人所需的最小船数 。 示例 1: 示例 2: 示例 3: 思路 典型的 N:M类型问题,类似的问题还有,N个进程每一类型用时不同,M个相同CPU,求最少时间,本质上也是求最小资源使用。类似的可以参考后面题目<项目调度器> 分析: 解题步骤: 代码 任务调度器 题目 leetcode:621. 任务调度器 给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。在任何一个单位时间,CPU 可以完成一个任务,或者处于待命状态。 然而,两个 相同种类 的任务之间必须有长度为整数 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。 你需要计算完成所有任务所需要的 最短时间 。 示例 1: 输入:tasks = ["A","A","A","B","B","B"], n = 2 输出:8 解释:A -> B -> (待命) -> A -> B -> (待命) -> A -> B 在本示例中,两个相同类型任务之间必须间隔长度为 n = 2 的冷却时间,而执行一个任务只需要一个单位时间,所以中间出现了(待命)状态。 示例 2: ["A","A","A","B","B","B"] ["A","B","A","B","A","B"] ["B","B","B","A","A","A"] ... 诸如此类 示例 3: A -> B -> C -> A -> D -> E -> A -> F -> G -> A -> (待命) -> (待命) -> A -> (待命) -> (待命) -> A 提示: 思路 分析: 可以分为两种情况: 步骤: PS: 上述过程简化的公式可以为: 代码 摆动序列 题目 leetcode:376.摆动序列 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。 子序列 可以通过从原始序列中删除一些(也可以不删除)元素来获得,剩下的元素保持其原始顺序。 给你一个整数数组 nums ,返回 nums 中作为 摆动序列 的 最长子序列的长度 。 思路 PS: 这个题目改个名字就很简单了:判断一个数组波峰波谷的和 分析: 代码 思路
算法考题
class Solution {
public:
std::string lowestString(std::vector
class Solution {
private:
std::vector
class Solution {
public:
int maxProfit(vector
class Solution {
public:
int numRescueBoats(vector
class Solution{
static bool cmp(int &a, int &b){
return a > b;
}
public:
int leastInterval(std::vector
class Solution {
public:
int wiggleMaxLength(vector
class Solution {
public int wiggleMaxLength(int[] nums) {
int n = nums.length;
if (n < 2) {
return n;
}
// 因为有边界节点(起点、终点)因此最少一个长度
int up = 1;
int down = 1;
for (int i = 1; i < n; i++) {
if (nums[i] > nums[i - 1]) {
up = down + 1;
}
if (nums[i] < nums[i - 1]) {
down = up + 1;
}
}
return Math.max(up, down);
}
}