122.买卖股票的最佳时机 II
class Solution {
public:
int maxProfit(vector<int>& prices) {
int sum=0;
for(int i=0; i<prices.size()-1; i++){
if(prices[i+1]-prices[i]>0){
sum+=prices[i+1]-prices[i];
}
}
return sum;
}
};
55. 跳跃游戏
给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
这个问题可以转化为跳跃覆盖范围究竟可不可以覆盖到终点。
贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点。
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(i+nums[i], cover);
if(cover>=nums.size()-1) return true;
}
return false;
}
};
- 时间复杂度: O(n)
- 空间复杂度: O(1)
45.跳跃游戏 II
给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
说明: 假设你总是可以到达数组的最后一个位置。
要从覆盖范围出发,不管怎么跳,覆盖范围内一定是可以跳到的,以最小的步数增加覆盖范围,覆盖范围一旦覆盖了终点,得到的就是最少步数!
移动下标达到了当前覆盖的最远距离下标时,步数就要加一,来增加覆盖距离。
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;
}
}
return ans;
}
};
1005.K次取反后最大化的数组和
给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次。(我们可以多次选择同一个索引 i。)
以这种方式修改数组后,返回数组可能的最大和。
局部最优:让绝对值大的负数变为正数,当前数值达到最大,整体最优:整个数组和达到最大。
class Solution {
public:
static bool cmp(const int a, const int b){
return abs(a)>abs(b);
}
int largestSumAfterKNegations(vector<int>& nums, int k) {
sort(nums.begin(), nums.end(), cmp);//根据abs来排序,因为如果都是正数的话,要反绝对值最小的数
//现在是从大到小排
for(int i=0; i<nums.size(); i++){
if(nums[i]<0&&k>0)
{
nums[i] = nums[i]*(-1);
k--;
}
}
while(k>0){
nums[nums.size()-1]*=-1;
k--;
}
// int sum=0;
return accumulate(nums.begin(), nums.end(), 0);
}
};
- 时间复杂度: O(nlogn)
- 空间复杂度: O(1)
用了排序时间复杂度是O(logn)