53. 最大子数组和(中等)
思路:dp或贪心,本质思路类似
// dp做法:每个元素都会决定是否继承之前和还是从自己开始
class Solution {
public int maxSubArray(int[] nums) {
int max = nums[0];
int dp[] = new int[nums.length];
dp[0] = nums[0];
for(int i=1;i<nums.length;i++){
dp[i] = Math.max(nums[i],dp[i-1]+nums[i]);
if(dp[i]>max)max = dp[i];
}
return max;
}
}
122. 买卖股票的最佳时机 II(中等)
思路:和摆动序列类似,但是只关注上升序列,每一个比pre大的元素都可以做差
class Solution {
public int maxProfit(int[] prices) {
int dp[] = new int[prices.length];
int pre = prices[0];
for(int i=1;i<prices.length;i++){
if(prices[i]>pre){
dp[i]+=(prices[i]-pre);
}
pre = prices[i];
dp[i]+=dp[i-1];
}
return dp[prices.length-1];
}
}
55. 跳跃游戏(中等)
思路:倒推,类似背包,贪心貌似更好一些
// dp:因为nums[i]是可以跳的最远距离,不能直接dp[i] = dp[i+nums[i]];
class Solution {
public boolean canJump(int[] nums) {
boolean dp[] = new boolean[nums.length];
dp[nums.length-1] = true;
for(int i=nums.length-2;i>=0;i--){
int jp = i+nums[i];
if(jp>=nums.length) dp[i] = true;
else for(int j=jp;j>i;j--) dp[i] = dp[i]|dp[j];
}
return dp[0];
}
}
// 贪心:记录每次可达的最后一个点,后续只需要比这个可达点大或相等即可。
class Solution {
public boolean canJump(int[] nums) {
int last = nums.length-1;
for(int i = nums.length-2;i>=0;i--){
if(i+nums[i] >= last)last = i;
}
return last == 0;
}
}
45. 跳跃游戏 II(中等)
思路:dp或贪心,和I类似
// dp,比较慢
class Solution {
public int jump(int[] nums) {
int dp[] = new int[nums.length];
Arrays.fill(dp,nums.length+1);
dp[nums.length-1] = 0;
for(int i = nums.length-2;i>=0;i--){
if(i+nums[i] >= nums.length-1)dp[i] = 1;
else for(int j=i+nums[i];j > i;j--)
dp[i] = Math.min(dp[i],dp[j]+1);
}
return dp[0];
}
}
// end 维护当前步可达的最远距离,maxdis维护下一步可达的最远距离
// 有的类似层序遍历
// 每次step++,都是计算的接下来的一层的步数,所以即使末尾比end小,依然会记录在内
// 经测试,题目样例均是存在可达解
class Solution {
public int jump(int[] nums) {
if(nums.length==1)return 0;
int maxdis = nums[0];
int step = 0;
int end = 0;
for(int i=0;i<nums.length;i++){
maxdis = Math.max(maxdis,i+nums[i]);
if(maxdis>=nums.length-1)return ++step;
if(i == end){
step++;
end = maxdis;
}
}
return step;
}
}
1005. K 次取反后最大化的数组和(简单)
全程stream 处理,主打一个优雅简洁
// 思路:按abs排序,abs大的负数取反,剩下的k机会处理abs小的正数
class Solution {
public int largestSumAfterKNegations(int[] nums, int k) {
long cnt = Arrays.stream(nums).filter(a -> a < 0).count();
int sum = Arrays.stream(nums).sum();
int min = cnt<k&&(k-cnt)%2!=0 ? Arrays.stream(nums).map(Math::abs).min().getAsInt():0;
return sum -2*min - 2*Arrays.stream(nums)
.boxed()
.sorted(Comparator.comparingInt(Integer::intValue))
.limit(cnt>=k?k:cnt)
.mapToInt(Integer::intValue)
.sum();
}
}