122.买股票的最佳时机
题目链接https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii
好巧妙的一道题啊,做之前完全不会想到这种解法。
局部最优:收集每天正利润
全局最优:求得最大利润
这道题只让你返回最大的利润和,不用管是哪几个相加的 思路就是:
我要算的区间的总利润就等于那个区间上我每天对前一天的利润之和,所以我不如求出我我每天对前一天的利润之和,只要为正我就加上,为负只会越加越小那我就不要这个数了。
class Solution {
public:
int maxProfit(vector<int>& prices) {
int result=0;
for(int i=1;i<prices.size();i++){
result+=max(prices[i]-prices[i-1],0);
}
return result;
}
};
55.跳跃游戏
题目链接:55. 跳跃游戏 - 力扣(LeetCode)
局部最优:每覆盖一个元素,尽可能的增加它的覆盖范围。
全局最优:看整体的覆盖范围能否到达终点
比如
下标0 1 2 3 4
元素2 3 1 1 4
思路感觉就是先从下标0开始,遍历到它所能跳的覆盖范围,看它覆盖的元素能不能增加它的覆盖范围,比如上面这个,如果我从0跳4下就能跳到终点,0+4>=5-1(cover>=nums.size()-1)就说明可以到达最后一个下标。
class Solution {
public:
bool canJump(vector<int>& nums) {
int cover=nums[0];
for(int i=0;i<=cover;i++){
cover=max(cover,nums[i]+i);
if(cover>=nums.size()-1){
return true;
}
}
return false;
}
};
45.跳跃游戏||
题目链接45. 跳跃游戏 II - 力扣(LeetCode)
局部最优:每一步都选覆盖范围内最大的那个点才计算步数
整体最优:到达终点时达到最小跳跃步数
因为题目保证能到达终点
我觉得的思路是我遍历到我现在能覆盖的范围(cur),到了覆盖范围cur的边缘了,我才跳一步,而且这一步的距离一定要是保存的最大距离next,然后我不断更新next的值,只要它到达终点就赶紧退出返回result的值。
class Solution {
public:
int jump(vector<int>& nums) {
int result = 0, cur = 0, next = 0;
if (nums.size() == 1)
return 0;
for (int i = 0; i < nums.size(); i++) {
next = max(next, i + nums[i]);
if (i == cur) {
cur = next;
result++;
if (next >= nums.size() - 1) {
break;
}
}
}
return result;
}
};
1005.k次取反后最大化的数组和
题目链接:1005. K 次取反后最大化的数组和 - 力扣(LeetCode)
局部最优:把绝对值大的负数变为正数,剩余的K把最小的正数进行取反
全局最优:整个数组达到最大
这里要进行绝对值比较是因为不进行绝对值比较的话最小的正数就不会在数组的最右边,不好找,
比如,如果是【-4,-2,3,5】; 我第一遍操作所有的负数,变为【4,2,3,5】; 我现在要找到2在哪并操作,很麻烦。 但如果我一开始按照绝对值降序排列【5,-4,3,-2】; 第一遍对负数操作完就是【5,4,3,2】; 此时2依旧还是在数组末尾,操作index-1即可
class Solution {
public:
static bool cmp(int a,int b){//要把cmp定义为static 因为sort里面只能接受对象
return abs(a)>abs(b);
}
int largestSumAfterKNegations(vector<int>& nums, int k) {
sort(nums.begin(),nums.end(),cmp);
for(int i=0;i<nums.size();i++){
if(nums[i]<0&&k>0){
nums[i]*=-1;
k--;
}
}
if(k%2==1){k为奇数就必须得乘一个就乘最小的那个正数
nums[nums.size()-1]*=-1;
}
int result=0;
for(int a:nums){
result+=a;
}
return result;
}
};