0
点赞
收藏
分享

微信扫一扫

数据结构与算法---算法篇之动态规划(一)

数据结构与算法—算法篇之动态规划(一)


什么是动态规划

动态规划本质

动态规划的特点

动态规划的解题思路:

动态规划问题一般从哪几个角度考虑

一句话概括:三特点四要素两本质

什么样的问题可以考虑使用动态规划解决呢?

比如:

解题步骤


话不多说,跟紧步伐,我们边看列题边学习


例题(详细剖析)

斐波那契数列

题目:

思路:
在这里插入图片描述

代码实现:

public class Solution {
    public int Fibonacci(int n) {
        //创建一个数组保存中间状态
        int[] arr = new int[n + 1];
        arr[0] = 0;
        arr[1] = 1;
        for(int i = 2;i <= n; i ++) {
            arr[i] = arr[i-1] + arr[i -2];
        }
        return arr[n];
    }
}

连续子数组的最大和

题目描述:

思路:

代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int n = s.nextInt();
            //把元素放入数组中
            int[] arr = new int[n];
            for (int i = 0; i < arr.length; i++) {
                arr[i] = s.nextInt();
        }
        System.out.println(func(arr));

    }
    public static int func(int[] arr) {
        if(arr.length == 0) {
            return 0;
        }
        int sum = arr[0];//临时最大值
        int maxSum = arr[0];//比较之后的最大值
        for (int i = 1; i < arr.length ; i++) {
            sum = Math.max(sum+arr[i],arr[i]);
            maxSum = Math.max(sum,maxSum);
        }
        return maxSum;

    }
}

公共子串计算

题目描述:

输入:
asdfas
werasdfaswer
输出:
6

思路:
在这里插入图片描述

牛客OJ链接

代码:

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()) {
            String str1 = sc.nextLine();
            String str2 = sc.nextLine();
            System.out.println(GetMaxLen(str1,str2));
        }
    }
    
    public static int GetMaxLen(String str1,String str2) {
        char[] arr1 = str1.toCharArray();
        char[] arr2 = str2.toCharArray();
        int len1= arr1.length;
        int len2 = arr2.length;
        int[][] maxSubLen = new int[len1+1][len2+1];
        int maxLen = 0;
        for(int i = 1;i <= len1;i++) {
            
            for(int j = 1;j <= len2;j++) {
                if(arr1[i -1] == arr2[j -1]) {
                    maxSubLen[i][j] = maxSubLen[i-1][j-1] + 1;
                }
                if(maxLen < maxSubLen[i][j]) {
                    maxLen = maxSubLen[i][j];
                }
            }
        }
        return maxLen;      
     }
}

字符串分割(Word Break)

题目描述:

思路:

在这里插入图片描述

牛客OJ链接

代码:

import java.util.*;
public class Solution {
    public boolean wordBreak(String s, Set<String> dict) {
        // boolean 数组
        boolean[] canBreak = new boolean[s.length()+1];
        // 初始化
        canBreak[0] = true;
        
        for(int i = 1;i <= s.length();i++) {
            
            //j < i && F(j) && [j+1,i] 
            for(int j = 0;j < i;j++) {
            //subString 左闭右开
                if(canBreak[j] && dict.contains(s.substring(j,i))) {
                    canBreak[i] = true;
                    break;
                }
            }
        }
        return canBreak[s.length()];
        
    }
}

字符串通配符

题目描述:

示例:

输入:te?t*.*
     txt12.xls
输出:false

输入:pq
     pppq
输出:false

输入:?*Bc*?
     abcd
输出:true

思路:

牛客链接

代码:

import java.util.*;
public class Main {
    public static void main(String args[]) {
        Scanner sc=new Scanner(System.in);
        while(sc.hasNextLine()){
            String t=sc.nextLine();
            String s=sc.nextLine();
            System.out.println(match(t,s));
        }
    }
    public static boolean match(String t,String s){
        char[] ct=t.toCharArray();
        char[] cs=s.toCharArray();
        int lt=ct.length;
        int ls=cs.length;
        boolean[][] dp=new boolean[ls+1][lt+1];
        dp[0][0]=true;
        for(int i=0;i<=ls;i++){
            for(int j=1;j<=lt;j++){
                if(ct[j-1]=='*'){
                    if(i==0){
                       dp[i][j]=dp[i][j-1];
                    }else{
                        if(cs[i-1]=='.' || (cs[i-1]>='0'&&cs[i-1]<='9') ||
                          (cs[i-1]>='a'&&cs[i-1]<='z') ||(cs[i-1]>='A'&&cs[i-1]<='Z')
                       ) {
                            dp[i][j]=dp[i-1][j] || dp[i][j-1];
                    }

                }
                    
            }else{
                    if(i>0 && defs(ct[j-1],cs[i-1])){
                        dp[i][j]=dp[i-1][j-1];
                  }
           }
        }           
    }
        return  dp[ls][lt];
}
    public static boolean defs(char t,char s){
        if(t=='?') return true;
        if(t>='a'&&t<='z'){
            t=(char)(t-'a'+'A');

        }
        if(s>='a'&&s<='z'){
            s=(char)(s-'a'+'A');
        }
        return s == t;
    }
}
    

总结

“种一颗树最好的是十年前,其次就是现在”
所以,
“让我们一起努力吧,去奔赴更高更远的山海”

如果有错误❌,欢迎指正哟😋

🎉如果觉得收获满满,可以动动小手,点点赞👍,支持一下哟🎉
在这里插入图片描述

举报

相关推荐

0 条评论