leetcode-动态规划3

今天是做动态规划做到发疯发狂失去理智的一天。
动态规划就是后一步要用到前一步的结果
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;    }}
发布了45 篇原创文章 · 获赞 4 · 访问量 1049

猜你喜欢

转载自blog.csdn.net/weixin_43838915/article/details/104764466