✨数据结构与算法—算法篇之动态规划(一)
什么是动态规划
动态规划本质
动态规划的特点
动态规划的解题思路:
动态规划问题一般从哪几个角度考虑
一句话概括:三特点四要素两本质
什么样的问题可以考虑使用动态规划解决呢?
比如:
解题步骤
话不多说,跟紧步伐,我们边看列题边学习
例题(详细剖析)
斐波那契数列
题目:
思路:
代码实现:
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;
}
}
总结
“种一颗树最好的是十年前,其次就是现在”
所以,
“让我们一起努力吧,去奔赴更高更远的山海”
如果有错误❌,欢迎指正哟😋
🎉如果觉得收获满满,可以动动小手,点点赞👍,支持一下哟🎉