二十八天补打卡,贪心算法的思路能想到,但代码比较难实现
122.买卖股票的最佳时机Ⅱ
做题过程
- 用贪心,只要后一天的股价比前一天的高,那就加上这一天利润,否则不做操作
- 用动态规划,用数组记下每一天持有和不持有股票的最大利润
知识点
- 局部最优:收集每天的正利润,全局最优:求得最大利润。时间复杂度:O(n),空间复杂度:O(1)
- 动态规划时间复杂度:O(n),空间复杂度:O(n)
动态规划
class Solution {
public:
int maxProfit(vector<int>& prices) {
vector<vector<int>>dp(prices.size(), vector<int>(2));
dp[0][0] = -prices[0]; // 持有股票最大利润
dp[0][1] = 0; // 不持股票最大利润
for (int i = 1; i < prices.size(); i++) {
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
dp[i][1] = max(dp[i - 1][0] + prices[i], dp[i - 1][1]);
}
return dp.back()[1];
}
};
55.跳跃游戏
做题过程
- 想到用一个数组去更新最大覆盖面积,但只用一个数就行
知识点
- 贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点。
- 时间复杂度: O(n)
- 空间复杂度: O(1)
贪心算法
class Solution {
public:
bool canJump(vector<int>& nums) {
int cover = 0;
if (nums.size() == 1) return true;
for (int i = 0; i <= cover; i++) {
cover = max(cover, nums[i] + i);
if (cover >= nums.size() - 1) return true;
}
return false;
}
};
45.跳跃游戏Ⅱ
做题过程
- 本题除了这次能到达的最大距离,也需要考虑到下一次能到达的最大距离,不愧是中等题有思路但写不出来
知识点
- 移动下标达到了当前覆盖的最远距离下标时,步数就要加一,来增加覆盖距离。最后的步数就是最少步数。
贪心算法
class Solution {
public:
int jump(vector<int>& nums) {
if (nums.size() == 1) return 0;
int curDistance = 0; // 当前覆盖最远距离下标
int ans = 0; // 记录走的最大步数
int nextDistance = 0; // 下一步覆盖最远距离下标
for (int i = 0; i < nums.size(); i++) {
nextDistance = max(nums[i] + i, nextDistance); // 更新下一步覆盖最远距离下标
if (i == curDistance) { // 遇到当前覆盖最远距离下标
ans++; // 需要走下一步
curDistance = nextDistance; // 更新当前覆盖最远距离下标(相当于加油了)
if (nextDistance >= nums.size() - 1) break; // 当前覆盖最远距到达集合终点,不用做ans++操作了,直接结束
}
}
return ans;
}
};
1005.K次取反后最大化的数组和
做题思路
- 想着用ifelse做,但逻辑比较复杂。
- 本题的解题步骤为:
- 第一步:将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小
- 第二步:从前向后遍历,遇到负数将其变为正数,同时K–
- 第三步:如果K还大于0,那么反复转变数值最小的元素,将K用完
- 第四步:求和
贪心
class Solution {
public:
static bool cmp(int a, int b) {
return abs(a) > abs(b);
}
int largestSumAfterKNegations(vector<int>& nums, int k) {
int result = 0;
sort(nums.begin(), nums.end(), cmp);
for (int i = 0; i < nums.size(); i++) {
if (nums[i] < 0 && k > 0) {
nums[i] = -nums[i];
k--;
};
}
if (k % 2 == 1) nums[nums.size() - 1] *= -1;
for (int n : nums) result += n;
return result;
}
};