LeetCode动态规划入门(专项打卡21天合集)

Posted 白鳯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode动态规划入门(专项打卡21天合集)相关的知识,希望对你有一定的参考价值。

【LeetCode】动态规划入门(专项打卡21天合集)

下图为证


Day1

斐波拉契数

509. 斐波那契数

class Solution {
    public int fib(int n) {
        int[] dp = new int[31];
        dp[1] = 1;
        for (int i = 2; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
}

第 N 个泰波那契数

1137. 第 N 个泰波那契数

class Solution {
    public int tribonacci(int n) {
        int[] dp = new int[38];
        dp[1] = dp[2] = 1;
        for (int i = 3; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
        }
        return dp[n];
    }
}

Day2

爬楼梯

70. 爬楼梯

class Solution {
    public int climbStairs(int n) {
        if (n < 3) return n;
        int cur = 2, pre = 1;
        for (int i = 3; i <= n; i++) {
            int temp = cur;
            cur += pre;
            pre = temp;
        }
        return cur;
    }
}

使用最小花费爬楼梯

746. 使用最小花费爬楼梯

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        int[] dp = new int[n];
        dp[0] = cost[0];
        dp[1] = cost[1];
        for (int i = 2; i < n; i++) {
            dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];
        }
        return Math.min(dp[n - 2], dp[n - 1]);
    }
}

Day3

打家劫舍

198. 打家劫舍

class Solution {
    public int rob(int[] nums) {
        int n = nums.length;
        int[] dp = new int[n + 1];
        dp[1] = nums[0];
        for (int i = 1; i < n; i++) {
            dp[i + 1] = Math.max(dp[i], dp[i - 1] + nums[i]);
        }
        return dp[n];
    }
}

打家劫舍 II

213. 打家劫舍 II

class Solution {
    public int rob(int[] nums) {
        if (nums == null || nums.length == 0) return 0;
        if (nums.length == 1) return nums[0];
        int val1 = rob1(nums);
        reverse(nums);
        int val2 = rob1(nums);
        return Math.max(val1, val2);
    }

    public int rob1(int[] nums) {
        int n = nums.length;
        int[] dp = new int[n + 1];
        dp[1] = nums[0];
        for (int i = 1; i < n; i++) {
            dp[i + 1] = Math.max(dp[i], dp[i - 1] + nums[i]);
        }
        return dp[n - 1];
    }

    private void reverse(int[] nums) {
        int n = nums.length, i = 0;
        while (i < n / 2) {
            int t = nums[i];
            nums[i] = nums[n - i - 1];
            nums[n - i - 1] = t;
            i++;
        }
    }
}

删除并获得点数

740. 删除并获得点数

class Solution {
    public int deleteAndEarn(int[] nums) {
        int n = 10000;
        int[] mark = new int[n + 1];
        for (int num : nums) mark[num] += num;
        int[] dp = new int[n + 2];
        dp[1] = mark[0];
        for (int i = 1; i < n + 1; i++) {
            dp[i + 1] = Math.max(dp[i], dp[i - 1] + mark[i]);
        }
        return dp[n + 1];
    }
}

Day4

跳跃游戏

55. 跳跃游戏

前向遍历

class Solution {
    public boolean canJump(int[] nums) {
        int ri = 0;
        for (int i = 0; i < nums.length; i++) {
            if (ri >= i) {
                ri = Math.max(ri, i + nums[i]);
            } else {
                return false;
            }
        }
        return true;
    }
}

后向遍历

class Solution {
    public boolean canJump(int[] nums) {
        if(nums == null || nums.length < 2) return true;
        int le = nums.length - 1;
        for(int i = nums.length - 2; i >= 0; i--) {
            if(i + nums[i] >= le) le = i;
        }
        return le == 0;
    }
}

跳跃游戏 II

45. 跳跃游戏 II

动态规划法

class Solution {
    public int jump(int[] nums) {
        int n = nums.length;
        int[] dp = new int[n + 1];
        for (int i = 0; i < nums.length; i++) {
            for (int j = 1; j <= nums[i] && i + j < n; j++) {
                dp[i + j] = dp[i + j] == 0 ? dp[i] + 1 : Math.min(dp[i + j], dp[i] + 1);
            }
        }
        return dp[n - 1];
    }
}

贪心法

class Solution {
    public int jump(int[] nums) {
        int steps = 0;
        int reach = 0, nextreach = 0;
        for (int i = 0; i < nums.length - 1; i++) {
            nextreach = Math.max(nextreach, i + nums[i]);
            if (reach == i) {
                reach = nextreach;
                steps++;
            }
        }
        return steps;
    }
}

Day5

最大子序和

53. 最大子序和

class Solution {
    public int maxSubArray(int[] nums) {
        int res = nums[0], cur = nums[0];
        for (int i = 1; i < nums.length; i++) {
            cur = cur > 0 ? cur + nums[i] : nums[i];
            res = Math.max(res, cur);
        }
        return res;
    }
}

环形子数组的最大和

918. 环形子数组的最大和

class Solution {
    public int maxSubarraySumCircular(int[] nums) {
        int max, min, curMax, curMin, sum;
        max = min = curMax = curMin = sum = nums[0];
        for (int i = 1; i < nums.length; i++) {
            sum += nums[i];
            curMax = curMax > 0 ? curMax + nums[i] : nums[i];
            max = Math.max(max, curMax);
            curMin = curMin < 0 ? curMin + nums[i] : nums[i];
            min = Math.min(min, curMin);
        }
        return max < 0 ? max : Math.max(max, sum - min);
    }
}

Day6

乘积最大子数组

152. 乘积最大子数组

class Solution {
    public int maxProduct(int[] nums) {
       int res, max, min;
       res = max = min = nums[0];
       for (int i = 1; i < nums.length; i++) {
           int mx = max, mn = min;
           max = Math.max(mx * nums[i], Math.max(mn * nums[i], nums[i]));
           min = Math.min(mx * nums[i], Math.min(mn * nums[i], nums[i]));
           res = Math.max(res, max);
       } 
       return res;
    }
}

乘积为正数的最长子数组长度

1567. 乘积为正数的最长子数组长度

class Solution {
    public int getMaxLen(int[] nums) {
        int res = 0, p = 0, q = 0;
        for (int num : nums) {
            if (num == 0) {
                p = q = 0;    //乘积为正负的长度
            } else {
                if (num > 0) {
                    p++;
                    if (q > 0) q++;
                } else {
                    int t = p;
                    p = q;
                    q = t;
                    q++;
                    if (p > 0) p++;
                }
            }
            res = Math.max(res, p);
        }
        return res;
    }
}

Day7

最佳观光组合

1014. 最佳观光组合

class Solution {
    public int maxScoreSightseeingPair(int[] values) {
        int res = 0, leftMax = 0;
        for (int i = 0; i < values.length; i++) {
            res = Math.max(res, leftMax + values[i] - i);
            leftMax = Math.max(leftMax, values[i] + i);
        }
        return res;
    }
}

买卖股票的最佳时机

121. 买卖股票的最佳时机

class Solution {
    public int maxProfit(int[] prices) {
        int profit = 0, minPrice = 10001;
        for (int price : prices) {
            minPrice = Math.min(minPrice, price);
            profit = Math.max(profit, price - minPrice);
        }
        return profit;
    }
}

买卖股票的最佳时机 II

leetcode专项 动态规划入门

leetcode专项 动态规划入门

leetcode专项 动态规划入门

每日算法&面试题⚡动态规划21天——第二天

⚡冲刺大厂每日算法&面试题⚡动态规划21天——第一天

冲刺大厂每日算法&面试题,动态规划21天——第七天