第一题:
链接:300. 最长递增子序列 - 力扣(LeetCode)
解题思路:
题目给出条件 :无序数组
题目要求 : 最长递增子序列
返回条件 : 最长字序列长度
采用方法 :动态规划(将大问题分为小问题)
大问题 : 寻找最长子序列
小问题 : 前一个数据 < 后一个数据
边界条件 : nums == 0 return 0
创建记录数组 :dp[nums,length]
初值 : dp[0] = 1
动态方程 : dp[i] = max(dp[j] + 1);
循环 : 外循环确定当前子序列最大数值 :nums[i];
内循环 寻找符合子序列
通过max找出最大dp[i];
返回最大值;
class Solution {
public int lengthOfLIS(int[] nums) {
if (nums.length == 0) {
return 0;
}
int[] dp = new int[nums.length];
int max = 1;
dp[0] = 1;
for(int i = 1 ; i < nums.length ; i++){
dp[i] = 1;
for(int j = 0 ; j < i ;j++){
if(nums[i] > nums[j]){
dp[i] = Math.max(dp[i] , dp[j] + 1);
}
}
max = Math.max(max,dp[i]);
}
return max;
}
}
第二题:
解题思路:
题目给出条件 : 金钱可以转换的额度、需要转换的金钱总数
题目要求 : 最少找零金钱份数
返回条件 : 数量
解题方法:动态规划
解题步骤:
界限 :当总金额为0 ;找零数量为0
可找份额a[j] 金钱总额(i) 找零数量 1、2、5 0 f(0) = 0 1、2、5 1 min(f(1-1),f(1-2),f(1-5))+1 = 1 1、2、5 2 min(f(2-1),f(2-2),f(2-5)+1 = 1 1、2、5 3 min(f(3-1),f(3-2),f(3-5))+1 = 2 注意 : f(1-5),f(2-5)等情况肯定不符合要求、不然人家还得给你补钱
状态转移方程
min = Math.min(f(i - a[j])+1;
接下来就按照思路敲:
class Solution {
public int coinChange(int[] coins, int amount) {
if(coins.length == 0) return -1;
int[] a = new int[amount+1];
a[0] = 0;
for(int i = 1 ; i <= amount ; i++){
int min = Integer.MAX_VALUE;
for(int j = 0 ; j < coins.length ; j++){
//这里就将那些 f(1-5)的过滤掉了,如何后面判断就找最小值
if(i - coins[j] >= 0 && a[i - coins[j]] < min){
min = a[i- coins[j]]+1;
}
}
//将最小值给f(i),下一次查到时直接使用;
a[i] = min;
}
return a[amount] == Integer.MAX_VALUE ? -1 : a[amount];
}
}