leetcode-dp
时间:2019-12-12
本文章向大家介绍leetcode-dp,主要包括leetcode-dp使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
参考文章
https://blog.csdn.net/u013309870/article/details/75193592
https://blog.csdn.net/baidu_28312631/article/details/47418773
动态规划
凡是可以大事化小的都可以用动态规划
一般解题步骤:找出最优子结构,找到状态转移方程,找到边界值
动态规划和贪心算法的区别
https://blog.csdn.net/weixin_39332529/article/details/89440114
最大的区别:贪心是通过局部最优解推导全局最优解
dp是通过所有的最优解推导全局最优解
所以贪心算法推到的全局最优解未必正确
dp常见题目
第一道题目展示dp的优点,将阶时间复杂度
import java.util.HashMap;
import java.util.Map;
/**
* You are climbing a stair case. It takes n steps to reach to the top.
*
* Each time you can either climb 1 or 2 steps. In how many distinct ways can
* you climb to the top?
*
* Note: Given n will be a positive integer.
*
* Example 1:
*
* Input: 2 Output: 2 Explanation: There are two ways to climb to the top. 1. 1
* step + 1 step 2. 2 steps Example 2:
*
* Input: 3 Output: 3 Explanation: There are three ways to climb to the top. 1.
* 1 step + 1 step + 1 step 2. 1 step + 2 steps 3. 2 steps + 1 step
*
*/
public class Lc70 {
/*
* 递归: fn=fn-1+fn-2; f1=1 f2=2
*/
public static int climbStairs(int n) {
if (n == 1) {
return 1;
}
if (n == 2) {
return 2;
}
return climbStairs(n - 1) + climbStairs(n - 2);
}
/*
* 递归优化 备忘录
*/
public static int climbStairs1(int n) {
if (n == 1) {
return 1;
}
if (n == 2) {
return 2;
}
Map<Integer, Integer> map = new HashMap<>();
if (map.containsKey(n)) {
return map.get(n);
} else {
int value = climbStairs1(n - 1) + climbStairs1(n - 2);
map.put(n, value);
return value;
}
}
/**
* 动态规划
*
* 最优子结构:最后一步到顶点的步长? 状态转移方程: 若最后一步走一步,之前到最后一步为x种,若最后一步走俩步,则到最后一步有y中,那么到最后顶点为 x+y
* 边界:f1=1; f2=2;
*
* @param n
* @return
*/
public static int climbStairs2(int n) {
if (n == 1) {
return 1;
}
if (n == 2) {
return 2;
}
int a = 1;// ’走台阶1
int b = 2;// ‘走台阶2
for (int i = 3; i <= n; i++) {
int temp = a + b;// 走当前台阶等于上一次加上上一次
a = b;
b = temp;
}
return b;
}
public static void main(String[] args) {
System.out.println(climbStairs(10));
System.out.println(climbStairs1(10));
System.out.println(climbStairs2(10));
}
}
之后的题目展示dp常见的类型
import java.util.Arrays;
/**
* Perfect Squares
*
*/
public class Lc279 {
/**
* dp 最优子结构:完全平方数个数等于 非完全平方数 + 1(完全平方数) 状态转移方程:dp[n] =
* min(dp[a-x*x]+1,dp(a+x*x)) 边界值 所有的平方值为1
*/
public static int numSquares(int n) {
int[] dp = new int[n + 1];
Arrays.fill(dp, Integer.MAX_VALUE);
for (int i = 0; i * i <= n; i++) {
dp[i * i] = 1;
}
for (int i = 0; i <= n; i++) {
for (int j = 0; i + j * j <= n; j++) {
dp[i + j * j] = Math.min(dp[i + j * j], dp[i] + 1);
}
}
return dp[n];
}
public static void main(String[] args) {
System.out.println(numSquares(12));
}
}
import java.util.ArrayList;
import java.util.List;
/**
* 问题: Given a non-empty string s and a dictionary wordDict containing a list of
* non-empty words, determine if s can be segmented into a space-separated
* sequence of one or more dictionary words.
*
*/
public class Lc139 {
/**
* dp 最优子结构:若0到i截取的串可以匹配,若i到末尾也可以匹配则证明可以被串都匹配;
*
* 状态转移方程:dp[i] = true
*
* dp[j]= true dp[0] = true
*/
public static boolean wordBreak(String s, List<String> wordDict) {
int len = s.length();
boolean[] dp = new boolean[len + 1];
dp[0] = true;
for (int i = 1; i <= len; i++) {
for (int j = i - 1; j >= 0 && !dp[i]; j--) {
String str = s.substring(j, i);
dp[i] = dp[j] && wordDict.contains(str);
}
}
return dp[len];
}
public static void main(String[] args) {
String s = "leetcode";
String s1 = "leet";
String s2 = "code";
List<String> wordDict = new ArrayList<String>();
wordDict.add(s1);
wordDict.add(s2);
System.out.println(wordBreak(s, wordDict));
}
}
这是dp找最大路径的模型
/**
* 数字三角形,求最大路径和
*
*/
public class LcMaxSum {
public static int maxSum(int[][] array) {
if (array == null) {
return 0;
}
int row = array.length;
int dp[] = array[row - 1];
for (int i = row - 2; i >= 0; i--) {
for (int j = 0; j < array[i].length; j++) {
dp[j] = Math.max(array[i][j] + dp[j], array[i][j] + dp[j + 1]);
}
}
return dp[0];
}
public static void main(String[] args) {
int[][] array = { { 1 }, { 2, 3 }, { 4, 5, 6 } };
System.out.println(maxSum(array));
}
}
/**
* You are a professional robber planning to rob houses along a street. Each
* house has a certain amount of money stashed, the only constraint stopping you
* from robbing each of them is that adjacent houses have security system
* connected and it will automatically contact the police if two adjacent houses
* were broken into on the same night.
*
* Given a list of non-negative integers representing the amount of money of
* each house, determine the maximum amount of money you can rob tonight without
* alerting the police.
*/
public class Lc198 {
/*
* 若dp[i]表示为当前最大值 则对于某个位置i ,存在取和不取,即dp[i-2]+num[i],dp[i-1]
* 则状态转移方程max(dp[i-2]+num[i],dp[i-1])
*/
public static int rob(int[] nums) {
if (nums.length == 0) {
return 0;
}
int dp[] = new int[nums.length];
if (nums.length >= 1) {
dp[0] = nums[0];
}
if (nums.length >= 2) {
dp[1] = Math.max(nums[0], nums[1]);
}
if (nums.length >= 3) {
for (int i = 2; i < nums.length; i++) {
dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);
}
}
return dp[nums.length - 1];
}
public static void main(String[] args) {
int[] nums = { 2, 1, 1, 2 };
System.out.println(rob(nums));
}
}
原文地址:https://www.cnblogs.com/xiaoshahai/p/12023454.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 一文学会注解的正确使用姿势
- 面试官:请算出走迷宫需要的最少步数
- lua执行redis脚本找不到脚本的问题
- Android |《看完不忘系列》之dagger
- Android | dagger细枝篇
- ES UpdateByQuery Java Api
- [Bazel]repository_rule() vs rule()
- Windows 系统信息收集姿势
- 小白学PyTorch | 3 浅谈Dataset和Dataloader
- 小白学PyTorch | 4 构建模型三要素与权重初始化
- 小白学PyTorch | 5 torchvision预训练模型与数据集全览
- 细品redis的Scan和Keys命令
- if语句与while语句
- 内网渗透 | 基于IPC的横向移动
- 【DB笔试面试866】队列等待之enq: TX - allocate ITL entry