今天是做动态规划做到发疯发狂失去理智的一天。
动态规划就是后一步要用到前一步的结果
139.单词拆分
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
拆分时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。
这道题的思路跟之前的凑零钱,凑完全平方数的和的解法类似,都是第n步时,有多种n-1步的情况,所以需要遍历不同的情况,然后选则一个最小的满足的情况。一般来说,求啥dp[n]就记录啥,比如这类题求是否可以拆分,dp[i]就记录0到i的字符串是否可以拆分,比如求多少种方法的,dp[i]就记录凑到i有多少种方法。
class Solution {
public boolean wordBreak(String s, List<String> wordDict)
{//dp[n]=dp[n]||dp[n-word]
boolean []dp=new boolean [s.length()+1];
for(int i=1;i<=s.length();i++)
dp[i]=false;dp[0]=true;
for(int i=1;i<=s.length();i++){
for(String word:wordDict){
if(i-word.length()>=0&&dp[i]==false) {
String temp=s.substring(0,i);
if(temp.equals(s.substring(0,i-word.length())+word))
dp[i]=dp[i]||dp[i-word.length()];//要并上dp[i]防止前面出现匹配的但是遍历到后面不匹配记录下不匹配的值}
}}
return dp[s.length()]; } }
300.最长上升子序列
给定一个无序的整数数组,找到其中最长上升子序列的长度。
类似的,dp[i]记录到i的最长长度,然后这里不会出现多种n-1步的情况,只需要找到比这个数小的那个数的长度加一。
class Solution {
public int lengthOfLIS(int[] nums) {
//dp[n]=dp[n-1]+1 nums[n]>nums[n-1]
//dp[0]=1;
if(nums.length==0)
return 0;
int dp[]=new int [nums.length];
dp[0]=1;int maxlen=1;
for(int i=1;i<nums.length;i++)
{
int j=i-1;dp[i]=1;int max=0;
while(j>=0)
{
if(nums[j]<nums[i])
max=Math.max(max,dp[j]);
j--; }
dp[i]=max+1;
maxlen=Math.max(dp[i],maxlen); }
return maxlen; }}
91.解码方法
一条包含字母 A-Z 的消息通过以下方式进行了编码:
‘A’ -> 1
‘B’ -> 2
…
这道题也是dp[i]记录第i位有几种编码,这道题其实每一位都只有一种可能,就是第n位确定了,跟第n-1位的组合就只有一个结果,所以不需要遍历,但是这种题要考虑很多的情况,所以状态方程要考虑好。
dp[i]=dp[i-2] i=0&(i-1=1|i-1=2)
dp[i]=dp[i-1]+dp[i-2] (i-1=1|i-1=2&<0i<7)&i!=0
dp[i]=dp[i-1] otherwise
class Solution { public int numDecodings(String s) { int []res=new int [s.length()+1]; res[0]=1; if(s.charAt(0)!='0') {res[1]=1;} else return 0; for(int i=1;i<s.length();i++) { if(s.charAt(i)=='0') {if(s.charAt(i-1)=='1'||s.charAt(i-1)=='2') res[i+1]=res[i-1]; else return 0;} else if(s.charAt(i-1)=='1'||(s.charAt(i-1)=='2'&&s.charAt(i)>'0'&&s.charAt(i)<'7')) res[i+1]=res[i-1]+res[i]; else res[i+1]=res[i]; } return res[s.length()]; }}
152.乘积最大子序列
给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数)。
这道题解法有点骚,学习了学习了
class Solution { public int maxProduct(int[] nums) { int max=1,min=1,maxlen=Integer.MIN_VALUE; for(int i=0;i<nums.length;i++) { if(nums[i]<0) { int temp=min; min=max; max=temp; } max=Math.max(nums[i]*max,nums[i]); min=Math.min(nums[i]*min,nums[i]); maxlen=Math.max(max,maxlen); } return maxlen; }}