LeetCode动态规划入门(专项打卡21天合集)
Posted 白鳯
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode动态规划入门(专项打卡21天合集)相关的知识,希望对你有一定的参考价值。
【LeetCode】动态规划入门(专项打卡21天合集)
下图为证
文章目录
Day1
斐波拉契数
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 个泰波那契数
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
爬楼梯
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;
}
}
使用最小花费爬楼梯
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
打家劫舍
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
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++;
}
}
}
删除并获得点数
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
跳跃游戏
前向遍历
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
动态规划法
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
最大子序和
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;
}
}
环形子数组的最大和
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
乘积最大子数组
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;
}
}
乘积为正数的最长子数组长度
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
最佳观光组合
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;
}
}
买卖股票的最佳时机
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;
}
}