动态2
来源:互联网 发布:大数据清洗工具 编辑:程序博客网 时间:2024/06/07 06:22
374. Guess Number Higher or Lower
要求:跟定一个数的最大值,每次得到大还是小或者相等
思路:二分
375. Guess Number Higher or Lower II
要求:给定一个数,猜错要交钱,最小花多少钱
思路: dfs +memo,需要遍历小的数到大的数
322. Coin Change
找零钱问题
要求:找零钱,给定总额,给定货币的种类,输出最小的硬币个数
思路:这个跟数组可否恰好二分,背包问题本质上是同一种问题,就是可选可不选的状态
错误:初始化都是Integer.MAX_VALUE,然后对硬币进行遍历,没有对 i - j 判断是否是Integer.MAX_VALUE
ac
486. Predict the Winner
要求:与海盗分金子题目要求类似,一堆金子两头取
思路:也可以采用Math.min();The dp[i][j] saves how much more scores that the first-in-action player will get from i to j than the second player. First-in-action means whomever moves first. You can still make the code even shorter but I think it looks clean in this way.
// 海盗分金子的问题 public boolean PredictTheWinner(int[] nums) { if (nums == null || nums.length <= 1) return true; int[] sum = new int[nums.length + 1]; sum[0] = 0; int len = nums.length; for (int i = 1; i <= len; i++) { sum[i] = sum[i - 1] + nums[i - 1]; } int[][] dp = new int[len + 1][len + 1]; for (int i = 1; i <= len; i++) { dp[i][i] = nums[i - 1]; } for (int l = 1; l < len; l++) { for (int i = 1; i <= len - l; i++) { int j = i + l; dp[i][j] = sum[j] - sum[i - 1] - Math.min(dp[i + 1][j] , dp[i][j - 1]); } } return 2 * dp[1][len] >= sum[len]; } //海盗分金问题的另外一个解法 public static int getMoney(int[] nums) { // if int m = nums.length; int[][][] memo = new int[m + 1][m + 1][2]; int[] resu = dfs(memo,nums, 0, m - 1, 0 ); System.out.println(Arrays.toString(resu)); return resu[0]; } public static int[] dfs(int[][][] memo, int [] nums, int le, int ri, int num) { int[] resu = new int[2]; if (le == ri) { if (num == 0) { resu[0] = nums[le]; resu[1] = 0; } else { resu[0] = 0; resu[1] = nums[le]; } return resu; } if (memo[le][ri][num] > 0) { return memo[le][ri]; } if (num == 0) { int temp1[] = dfs(memo, nums, le + 1, ri, 1); int max1 = temp1[0] + nums[le]; int temp2[] = dfs(memo, nums, le, ri - 1, 1); int max2 = temp1[0] + nums[ri]; if (max1 > max2) { temp1[0] = temp1[0] + nums[le]; memo[le][ri] = temp1; return temp1; } else { temp2[0] = temp2[0] + nums[ri]; memo[le][ri] = temp2; return temp2; } } if (num == 1) { int temp1[] = dfs(memo, nums, le + 1, ri, 0); int max1 = temp1[1] + nums[le]; int temp2[] = dfs(memo, nums, le, ri - 1, 0); int max2 = temp1[1] + nums[ri]; if (max1 > max2) { temp1[1] = temp1[1] + nums[le]; memo[le][ri] = temp1; return temp1; } else { temp2[1] = temp2[1] + nums[ri]; memo[le][ri] = temp2; return temp2; } } return null; }
486. Can I Win
思路:dfs加缓存,注意本次调用help函数,要取反
474. Ones and Zeroes
要求:给定0的个数以及1的个数,判定最多可以选择的组成的字符串的个数
思路:这个是0-1背包问题的类似问题,其实考试那个也是0- 1背包问题,这个是复杂版本的,背包定义dp[i][j],代表的是如果前i个占用j大的空间,转移方程为用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:
f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}
此处定义的dp[i][j]为占用的0 与1的个数,这里面有两个限制参数,时间复杂度为O(n立方)
// 背包问题,都是从包来进行考虑的 public int findMaxForm(String[] strs, int m, int n) { int[][] dp = new int[m+1][n+1]; for (String s : strs) { int[] count = count(s); for (int i=m;i>=count[0];i--) for (int j=n;j>=count[1];j--) dp[i][j] = Math.max(1 + dp[i-count[0]][j-count[1]], dp[i][j]); } return dp[m][n]; } public int[] count(String str) { int[] res = new int[2]; for (int i=0;i<str.length();i++) res[str.charAt(i) - '0']++; return res; }
416. Partition Equal Subset Sum
要求:数组里面元素的和能否组成一个特定的数
思路:可以优化的背包问题的
// 核心代码, 比上面少了一维度 for (int n : nums) { for (int i = sum; i>= n; i--) { dp[i] = dp[i] || dp[i - n]; } }
120. Triangle
要求:给定一个三角形,输出从根节点到叶子节点的类累加和最小的值
思路:三角形动态规划问题,如果涉及到路径的问题,可以采用pre缓存
每一个子节点从两个父节点继承
376. Wiggle Subsequence
要求:输出摇摆子序列的长度
思路:缓存两个, up, down,初始化的时候up和down都记为1,然后上升跟新up,下降更新do
输出:up和do大的那个
二叉查找树的题目
96. Unique Binary Search Trees
要求:给定一个数n,求1到n的n个数,可以组成多少种完全不同的二叉查找树
思路:G(n) = F(1, n) + F(2, n) + … + F(n, n). G(0)=1, G(1)=1. F(i, n) = G(i-1) * G(n-i) 1 <= i <= n
F 函数表示为以第i个结点为根节点,n个数的而查找树的个数 G(n) = G(0) * G(n-1) + G(1) * G(n-2) + … + G(n-1) * G(0)
ac:dp,注意下下标的范围,一般来讲,根据简单的demo进行测试即可
95. Unique Binary Search Trees II
要求:给定一个数n,输出组成不同的二叉查找树
思路:跟上一个 一样 采用 dfs,需要注意的是, 函数返回的是树的集合
377. Combination Sum IV
要求:给定目标值,数组里面有多少种可能结果集合
思路;这个是完全背包问题,与coinchange类似,只不过转移方程一个是最小的硬币数量,一个是最多的组合数量,不是0,1背包的问题 01背包,物品在外, 完全背包, 目标值在外(cionchange)
39. Combination Sum
要求:给定目标值,得出所有无重复的,数组中数的和等于当前值的目标值
思路:dfs+ backtracking, 一般结果输出型的,都得利用backtracking,
trick:因为是数,并且要求结果无重复,就要放一个start,下一次只能从start以及start的右侧进行选取,否则会出现重复
一般的题目,都是拐一个弯。注意下trick点,对比。
- 动态2
- 动态代理(2)----动态代理和AOP
- 动态代理(2)----动态代理和AOP .
- 动态规划2
- Delphi动态数组2
- 动态规划详解2
- 动态加载驱动-2
- 动态创建2
- 动态代理2
- 动态规划(2)
- 动态代理2
- 动态加载2
- 动态加载自己2
- 2-4动态列表
- 最近动态2
- 动态规划2
- 简谈--动态规划2
- 查找(2)--动态查找
- VS2017下OpenCV3.2学习笔记(一)安装配置、测试程序
- SQLite实现数据持久化存储小案例之购买商品
- C++ Boost::bind函数包装器使用,boost::bind与伪函数的绑定使用
- 封装RecycleView的Adapter并实现列表展示
- Atcoder Regular Contest 072 E Alice in Linear Land
- 动态2
- 5-33 有理数加法 (15分)
- 让自己成为有利用价值的人
- 实现简易版markdown同步滚动
- UE4材质初探
- 关于jQuery对html中的元素进行选择的选择器问题
- PAT乙级(Basic Level)练习题 >外星人的语言
- 稀疏矩阵及其逆置矩阵
- Oracle表连接方法 (上)