122. 买卖股票的最佳时机 II
借助了一点数学思维,类似于裂项相消。假设第m天买入,第n天卖出(n>m),则获得的利润就是(prices[n]-prices[n-1])+(prices[n-1]-prices[n-2])+…+(prices[m+1]-prices[m]),拆分为求单天的收入,收集正值的利润求和即为最大利润。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
1
)
O(1)
O(1)
// c++
class Solution {
public:
int maxProfit(vector<int>& prices) {
int sum=0;
for(int i=1; i<prices.size(); i++){
int tmp = prices[i] - prices[i-1];
if(tmp>0) sum+=tmp;
}
return sum;
}
};
*55. 跳跃游戏
这题属于猛一看很简单,仔细想就是想不出来。
需要分情况讨论一下:
- 数组中没有0,则一定可以到达数组最后一个位置。
- 数组中有0,则需要查看前面的单元格的最大覆盖范围是否可以跳过这个0位置。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
1
)
O(1)
O(1)
// c++
class Solution {
public:
bool canJump(vector<int>& nums) {
int cover=0;
for(int i=0; i<=cover; i++){
cover = max(i+nums[i], cover);
if(cover>=nums.size()-1) return true;
}
return false;
}
};
*45. 跳跃游戏 II
虽然和上题相似,但是依旧没思路。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
1
)
O(1)
O(1)
// c++
class Solution {
public:
int jump(vector<int>& nums) {
if(nums.size()==1) return 0;
int curCover=0, nextCover=0;
int cnt=0;
for(int i=0; i<nums.size(); i++){
nextCover = max(i+nums[i], nextCover);
if(i==curCover){
cnt++;
curCover = nextCover;
if(curCover>=nums.size()-1) break;
}
}
return cnt;
}
};
*1005. K 次取反后最大化的数组和
按照绝对值进行排序,排序后按绝对值从大到小将负值变为正值。若所有负值均变为正值后,k仍不为0,则将绝对值最小的元素反复变为相反数。
这里有一个小trick,一个正值变两次相反数仍然是自己,所以用k对2取余,若不为0,则将最小元素变为相反数。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
1
)
O(1)
O(1)
// c++
class Solution {
public:
static bool cmp(int a, int b){
return abs(a)<abs(b);
}
int largestSumAfterKNegations(vector<int>& nums, int k) {
sort(nums.begin(), nums.end(), cmp);
int result=0;
for(int i=nums.size()-1; i>=0 && k; i--) {
if(nums[i]<0) {
nums[i] *= -1;
k--;
}
}
if(k%2==1) nums[0]*=-1;
for(int a:nums) result+=a;
return result;
}
};