【代码随想录Day32】贪心算法/DP

文章介绍了在LeetCode上关于股票买卖最佳时机II和跳跃游戏系列的解题方法,包括贪心算法和动态规划的实现。对于股票问题,两种策略分别从不同角度计算最大利润。跳跃游戏中,贪心算法和动态规划解决是否能到达终点的问题,以及最小步数的求解。
摘要由CSDN通过智能技术生成

122 买卖股票的最佳时机II

https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/

class Solution {  //贪心,收集正数的每天利润
    public int maxProfit(int[] prices) {
        int sum = 0;
        for (int i = 1; i < prices.length; i++) {
            if (prices[i] > prices[i - 1]) sum += prices[i] - prices[i - 1];
        }
        return sum;
    }
}
class Solution { //dp
    public int maxProfit(int[] prices) {
        int hold = -prices[0];
        int unhold = 0;
        for (int i = 1; i < prices.length; i++) {
            int temp = hold;
            hold = Math.max(unhold - prices[i], hold);
            unhold = Math.max(temp + prices[i], unhold);
        }
        return unhold;
    }
}

55 跳跃游戏

https://leetcode.cn/problems/jump-game/ 贪心很不好想,TO(n) SO(1)比dp快,维护一个 maxCover,在maxCover范围内依次遍历时,更新maxCover,直到maxCover能到 end,否则就是跳不到返回false;

class Solution {  //贪心
    public boolean canJump(int[] nums) {
        int maxCover = 0;
        for (int i = 0; i <= maxCover; i++) {
            if (i == nums.length - 1) return true;
            maxCover = Math.max(maxCover, i + nums[i]);
        }
        return false;
    }
}
class Solution { //从前向后dp
    public boolean canJump(int[] nums) {
        boolean[] dp = new boolean[nums.length];  //可不可以从0跳到i
        dp[0] = true;
        for (int i = 1; i < nums.length; i++) {
            for (int j = 0; j < i; j++) {
                if (dp[j] && nums[j] + j >= i) {
                    dp[i] = true;
                    break;
                }
            }
        }
        return dp[nums.length - 1];
    }
}
class Solution {  //从后向前dp
    public boolean canJump(int[] nums) {
        boolean[] dp = new boolean[nums.length];  //i可不可以跳到end
        dp[nums.length - 1] = true;
        for (int i = nums.length - 2; i >= 0; i--) {
            for (int j = i + 1; j <= i + nums[i]; j++) {
                if (j >= nums.length - 1 || dp[j] == true) {
                    dp[i] = true;
                    break;
                } 
            }
        }
        return dp[0];
    }
}

45 跳跃游戏II

https://leetcode.cn/problems/jump-game-ii/

由于要求最小步数,每走到maxCover时需要增加步数,增加一步后新的maxCover需要靠之前遍历过程中记录跟新NextCover得到。

class Solution {  //贪心, 需要把能到的地方按步数分层次,遍历时更新nextCov,当i到达maxCover时,加步数并把nextCov给maxCov
    public int jump(int[] nums) { 
        int maxCover = 0;          
        int maxNext = 0;           
        int minStep = 0;           
        for (int i = 0; i <= maxCover; i++) {
            if (i == nums.length - 1) break;
            maxNext = Math.max(maxNext, i + nums[i]);
            if (i == maxCover) {
                minStep++;
                maxCover = maxNext;
            } 
        }
        return minStep;
    }
}


class Solution {  //dp
    public int jump(int[] nums) {
        int[] dp = new int[nums.length];
        dp[nums.length - 1] = 0;
        for (int i = nums.length - 2; i >= 0; i--) {
            dp[i] = Integer.MAX_VALUE;                    
            if (i + nums[i] >= nums.length - 1) {             // bug nums[i] not dp[i]
                dp[i] = 1;
            } else {
                for (int j = 1; j <= nums[i]; j++) {                    //bug j <= nums[i] not j <= dp[i]
                    if (dp[i + j] != Integer.MAX_VALUE && dp[i] > dp[i + j] + 1) {
                        //dp[i] = Math.min(dp[i], dp[i + j] + 1);
                        dp[i] = dp[i + j] + 1;
                    }
                }
            }
        }
        return dp[0] == Integer.MAX_VALUE ? -1 : dp[0];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值